├── .editorconfig ├── COPYING ├── README ├── doc ├── .gitignore ├── language.pdf ├── language │ ├── grammar.tex │ └── language.tex ├── pseudocodes.pdf ├── pseudocodes │ ├── algorithm2e.sty │ ├── alp.bib │ ├── appendix.tex │ ├── assumptions.tex │ ├── buy.tex │ ├── cl-signature.tex │ ├── compact.tex │ ├── dlr.tex │ ├── endorsed.tex │ ├── equality.tex │ ├── fujisaki-okamoto.tex │ ├── hvzk.tex │ ├── multiplication.tex │ ├── params.tex │ ├── pedersen.tex │ ├── projects.tex │ ├── pseudo.sty │ ├── pseudocodes.tex │ ├── range.tex │ ├── sarah.bib │ ├── setup.tex │ ├── special-range.tex │ └── verifiable.tex └── usenix10.pdf └── src ├── .gitignore ├── Arbiter.cpp ├── Arbiter.h ├── Bank.cpp ├── Bank.h ├── BankParameters.cpp ├── BankParameters.h ├── BankTool.cpp ├── BankTool.h ├── BankWithdrawTool.cpp ├── BankWithdrawTool.h ├── BuyMessage.cpp ├── BuyMessage.h ├── Buyer.cpp ├── Buyer.h ├── CLBlindIssuer.cpp ├── CLBlindIssuer.h ├── CLBlindRecipient.cpp ├── CLBlindRecipient.h ├── CLSignatureProver.cpp ├── CLSignatureProver.h ├── CLSignatureVerifier.cpp ├── CLSignatureVerifier.h ├── CashException.cpp ├── CashException.h ├── Ciphertext.cpp ├── Ciphertext.h ├── Coin.cpp ├── Coin.h ├── CommonFunctions.cpp ├── CommonFunctions.h ├── Debug.h ├── FEContract.cpp ├── FEContract.h ├── FEInitiator.cpp ├── FEInitiator.h ├── FEMessage.h ├── FEResolutionMessage.h ├── FEResponder.cpp ├── FEResponder.h ├── FESetupMessage.cpp ├── FESetupMessage.h ├── FourSquares.cpp ├── FourSquares.h ├── Group.cpp ├── Group.h ├── GroupPrime.cpp ├── GroupPrime.h ├── GroupRSA.cpp ├── GroupRSA.h ├── GroupSquareMod.cpp ├── GroupSquareMod.h ├── Hash.cpp ├── Hash.h ├── Makefile ├── Merkle.cpp ├── Merkle.h ├── MerkleContract.h ├── MerkleProof.cpp ├── MerkleProof.h ├── MerkleProver.cpp ├── MerkleProver.h ├── MerkleVerifier.cpp ├── MerkleVerifier.h ├── MultiExp.cpp ├── MultiExp.h ├── NTL ├── ZZ.cpp ├── ZZ.h ├── tools.h └── vec_ZZ.h ├── ProgramMaker.cpp ├── ProgramMaker.h ├── Seller.cpp ├── Seller.h ├── Serialize.cpp ├── Serialize.h ├── Serialize_map.h ├── SigmaProof.cpp ├── SigmaProof.h ├── SigmaProver.cpp ├── SigmaProver.h ├── SigmaVerifier.cpp ├── SigmaVerifier.h ├── Signature.cpp ├── Signature.h ├── Test.cpp ├── Timer.cpp ├── Timer.h ├── UserTool.cpp ├── UserTool.h ├── UserWithdrawTool.cpp ├── UserWithdrawTool.h ├── VECiphertext.h ├── VEDecrypter.cpp ├── VEDecrypter.h ├── VEProver.cpp ├── VEProver.h ├── VEPublicKey.h ├── VESecretKey.h ├── VEVerifier.cpp ├── VEVerifier.h ├── Wallet.cpp ├── Wallet.h ├── ZKP ├── .cvsignore ├── ASTHVisitor.h ├── ASTNode.cpp ├── ASTNode.h ├── ASTTVisitor.h ├── ASTVisitor.h ├── BindGroupValues.cpp ├── BindGroupValues.h ├── CommitmentVisitor.cpp ├── CommitmentVisitor.h ├── ComputationVisitor.cpp ├── ComputationVisitor.h ├── ConstantProp.cpp ├── ConstantProp.h ├── ConstantSub.cpp ├── ConstantSub.h ├── DLRepresentation.cpp ├── DLRepresentation.h ├── DescribeRelations.cpp ├── DescribeRelations.h ├── Environment.cpp ├── Environment.h ├── EqualityProver.cpp ├── EqualityProver.h ├── EqualityVerifier.cpp ├── EqualityVerifier.h ├── ExponentSub.cpp ├── ExponentSub.h ├── ForExpander.cpp ├── ForExpander.h ├── Interpreter.cpp ├── Interpreter.h ├── InterpreterCache.h ├── InterpreterProver.cpp ├── InterpreterProver.h ├── InterpreterVerifier.cpp ├── InterpreterVerifier.h ├── MultiExpCache.h ├── PowerCache.h ├── Printer.cpp ├── Printer.h ├── Translator.cpp ├── Translator.h ├── TypeChecker.cpp ├── TypeChecker.h ├── TypeIdentifier.cpp ├── TypeIdentifier.h ├── UndefinedVariables.cpp ├── UndefinedVariables.h ├── UnusedVariables.cpp ├── UnusedVariables.h ├── ZKPLexer.cpp ├── ZKPLexer.hpp ├── ZKPParser.cpp ├── ZKPParser.hpp ├── ZKPParserTokenTypes.hpp ├── ZKPParserTokenTypes.txt ├── ZKPTest.cpp ├── examples │ ├── allkinds.txt │ ├── badDLR.txt │ ├── badmult.txt │ ├── cl-issue.txt │ ├── cl-obtain-ecash.txt │ ├── cl-prove-ecash.txt │ ├── cl.txt │ ├── compute.txt │ ├── declRange.txt │ ├── dlr.txt │ ├── ecash.txt │ ├── encrypt.txt │ ├── examples.txt │ ├── grammar.txt │ ├── modulus.txt │ ├── multiplication.txt │ ├── presig.txt │ ├── range.txt │ ├── simpleDLR.txt │ ├── try-range.txt │ ├── twoDL.txt │ ├── undef.txt │ ├── userid.txt │ ├── ve.txt │ └── vedecrypter.txt ├── grammar.txt └── zkp.g ├── bank.80.params ├── base64.cpp ├── base64.h ├── dsa.c ├── gdbinit4x ├── new_ptr.hpp ├── public.80.arbiter ├── public.regular.80.arbiter ├── secret.80.arbiter ├── secret.regular.80.arbiter ├── stl_views.gdb ├── tests └── proofs.cpp ├── tool.80.bank ├── tool.80.user └── wallet.80 /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | indent_style = space 5 | indent_size = 4 6 | -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | ZKPDL and Cashlib 2 | 3 | ZKPDL (Zero-Knowledge Proof Description Language) is a high-level 4 | language designed for specifying cryptographic operations and in 5 | particular zero-knowledge proofs. Its corresponding interpreter will, 6 | given a program and a set of inputs, output a proof when acting as the 7 | prover and verify a proof when acting as the verifier. 8 | 9 | The Cashlib library provides functionality for endorsed e-cash and 10 | fair exchange protocols. Classes are provided for withdrawing, 11 | spending, and depositing e-coins, as well as for bartering for files 12 | using an e-coin only as a placeholder. Resolution protocols are 13 | provided as well. 14 | 15 | For a detailed description of this software please see our paper in 16 | USENIX Security 2010: 17 | http://www.cs.brown.edu/research/brownie/usenix10.pdf 18 | 19 | Pseudocode descriptions of the cryptographic protocols used are 20 | available in the "doc/pseudocodes" directory. 21 | http://github.com/brownie/cashlib/raw/master/doc/pseudocodes.pdf 22 | 23 | A short manual describing our language syntax can also be found in the 24 | "doc/manual" directory. 25 | http://github.com/brownie/cashlib/raw/master/doc/language.pdf 26 | 27 | These documents are still under development and should improve in the 28 | future. 29 | 30 | Many example programs are available in the "src/ZKP/examples" directory. 31 | 32 | We would love to hear about your interest in ZKPDL and Cashlib. Feel 33 | free to contact us if you have any questions or comments! 34 | 35 | Chris Erway 36 | Sarah Meiklejohn 37 | 38 | The Brownie Points project 39 | brownie@cs.brown.edu 40 | http://www.cs.brown.edu/research/brownie/ 41 | -------------------------------------------------------------------------------- /doc/.gitignore: -------------------------------------------------------------------------------- 1 | *.aux 2 | *.dvi 3 | *.log 4 | *.out 5 | *.aux 6 | *.bbl 7 | *.blg 8 | *.out 9 | *.toc 10 | -------------------------------------------------------------------------------- /doc/language.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brownie/cashlib/8820b953f8d0377c35dab909f60168370edce168/doc/language.pdf -------------------------------------------------------------------------------- /doc/pseudocodes.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brownie/cashlib/8820b953f8d0377c35dab909f60168370edce168/doc/pseudocodes.pdf -------------------------------------------------------------------------------- /doc/pseudocodes/algorithm2e.sty: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brownie/cashlib/8820b953f8d0377c35dab909f60168370edce168/doc/pseudocodes/algorithm2e.sty -------------------------------------------------------------------------------- /doc/pseudocodes/appendix.tex: -------------------------------------------------------------------------------- 1 | \section{Common Functionalities} 2 | 3 | \textsc{Randomization}:\\ 4 | 5 | \begin{algorithm}[H]\label{randomize} 6 | \linesnumbered 7 | \SetKwComment{Comment}{}{} 8 | \SetKwInput{Pre}{Pre-conditions} 9 | \dontprintsemicolon 10 | 11 | \KwIn{Definition of the group, number of random elements $k$, number of fixed elements $l$, bases $g_1,\ldots,g_{k+l-1},h$, fixed elements $x_1,\ldots,x_l$ if any.} 12 | \Pre{$l < k$, $k \geq 1$, $l \geq 0$} 13 | \KwOut{random element $R$, random exponenets $openR$} 14 | \BlankLine 15 | 16 | \Comment{Randomize} \; 17 | \Indp 18 | Pick $k-1$ random numbers $s_i$ from the domain of randomness $D_R$. \; 19 | Pick another random number $t$ from the domain of randomness $D_R$. \; 20 | Compute $R = [\prod_{i=1}^{l} g_i^{x_i}] [\prod_{i=1}^{k-1} g_{l+i}^{s_i}] h^{t}$ using group operations. \; 21 | Output the random group element $R$ and random exponents $openR = s_1,\ldots,s_{k-1},t$. \; 22 | \Indm 23 | 24 | \caption{Procedure to generate a random group element with associated random exponents. Call this procedure \textbf{Randomize}.} 25 | \end{algorithm} 26 | 27 | -------------------------------------------------------------------------------- /doc/pseudocodes/assumptions.tex: -------------------------------------------------------------------------------- 1 | \section{Assumptions} 2 | The suggested security parameters above are set to satisfy the following 3 | assumptions (by conjecture). 4 | 5 | Strong RSA Assumption: For $N = pq$ with $p,q$ prime, it is difficult for any 6 | computationally bounded adversary $\A$ to compute $x$ on input $N$, $e$, and 7 | $y=x^e\bmod N$ 8 | for some $e$ such that $\gcd(e,\phi(N)) = 1$, even if $\A$ is allowed to pick 9 | $e$ itself (note that this last condition is what makes this assumption the 10 | ``strong'' verison of the standard RSA assumption). 11 | 12 | Discrete Logarithm Assumption: For a cyclic group $G$ of order $q$ with 13 | generator $g$, it is difficult for any computationally bounded adversary $\A$ 14 | to compute $x$ on input $g^x$, for $x\in{\Z_q}$. 15 | -------------------------------------------------------------------------------- /doc/pseudocodes/params.tex: -------------------------------------------------------------------------------- 1 | \section{Security Parameters}\label{sec-params} 2 | In our system, we will use a unified security parameter $ \security $, which corresponds to the conjecture that any attack that breaks the system must perform roughly $2^{\security}$ steps. We also define the following security parameters for ease of notation: 3 | 4 | $ \RSALength $ defines the bit-length of an RSA modulus. 5 | 6 | $ \stat $ defines the statistical security parameter. That is to say, two statistically indistinguishable distributions will be $2^{-\stat}$ close to each other. 7 | 8 | $ \hashLength $ defines the length of the output of a hash function used for collision resistance or as a random oracle. 9 | 10 | $ \orderLength $ defines the bit-length of the order of the prime-order group we will use. $ \primeLength $ defines the bit-length of the modulus of $Z_{\primeMod}^*$. The prime-order group will be a subgroup of $Z_{\primeMod}^*$ of order $ \primeOrder $. 11 | 12 | To get $ \security = 80 $, which is considered the bare minimum requirement for security, we need to have $ \RSALength = 1024 $, $ \stat = \security = 80 $, $ \hashLength = 2*\security = 160 $, $ \orderLength = 2*\security = 160 $, $ \primeLength = 1024 $. We will use these numbers for performance evaluation. The reasoning for hash functions and prime order is related to the birthday bound, and states the best known algorithms break them in $2^{\hashLength / 2}$ and $2^{\orderLength / 2}$ time respectively (DON'T WE NEED A CITATION FOR THIS?). We will use SHA-1 as our hash function. 13 | 14 | To get a longer-lasting security, we should use $ \security = 128 $, which corresponds to $ \RSALength = 2048 $, $ \stat = \security = 128 $, $ \hashLength = 2*\security = 256 $, $ \orderLength = 2*\security = 256 $, $ \primeLength = 1024 $. For our BitTorrent system, we should use AES-128 as the block cipher and SHA-256 as the hash function whenever necessary (note that these numbers correspond to $ \security = 112 $ \cite{RSAlabs1, RSAlabs2}). 15 | 16 | Finally, if we are feeling paranoid, we can easily set $ \RSALength = 4096 $, $ \primeLength = 2048 $, and use SHA-512 and AES-256. The only issue is that we will sacrifice some amount of efficiency. 17 | -------------------------------------------------------------------------------- /doc/pseudocodes/pseudo.sty: -------------------------------------------------------------------------------- 1 | \newcommand{\ea}{\emph{et al.} } 2 | \newcommand{\eg}{\emph{e.g.}, } 3 | \newcommand{\ie}{\emph{i.e.} } 4 | \newcommand{\etc}{\emph{etc.} } 5 | 6 | \newcommand{\accept}{\ensuremath{\mathsf{ACCEPT}}} 7 | \newcommand{\reject}{\ensuremath{\mathsf{REJECT}}} 8 | \newcommand{\error}{\ensuremath{\mathsf{ERROR}}} 9 | 10 | 11 | \newcommand{\security}{\ensuremath{\mathit{sec}}} 12 | \newcommand{\stat}{\ensuremath{\mathit{stat}}} 13 | \newcommand{\RSALength}{\ensuremath{\mathit{RSALength}}} 14 | \newcommand{\primeLength}{\ensuremath{\mathit{primeLength}}} 15 | \newcommand{\orderLength}{\ensuremath{\mathit{orderLength}}} 16 | \newcommand{\hashLength}{\ensuremath{\mathit{hashLength}}} 17 | 18 | \newcommand{\primeMod}{\ensuremath{\mathit{primeModulus}}} 19 | \newcommand{\primeOrder}{\ensuremath{\mathit{primeOrder}}} 20 | 21 | \newcommand{\cc}{\ensuremath{\mid\mid}} 22 | 23 | \newcommand{\hash}{\ensuremath{\mathit{hash}}} 24 | \newcommand{\info}{\ensuremath{\mathit{info}}} 25 | \newcommand{\ses}{\ensuremath{\mathit{ses}}} 26 | 27 | \newcommand{\hk}{\ensuremath{\mathit{hk}}} 28 | \newcommand{\abs}{\ensuremath{\mathit{abs}}} 29 | 30 | \newcommand{\A}{\mathcal{A}} 31 | \newcommand{\Z}{\mathbb{Z}} 32 | -------------------------------------------------------------------------------- /doc/pseudocodes/pseudocodes.tex: -------------------------------------------------------------------------------- 1 | \documentclass[letterpaper,11pt]{article} 2 | \usepackage{fullpage} 3 | \usepackage[ruled,noend,linesnumbered]{algorithm2e} 4 | \usepackage{amsfonts} 5 | \usepackage{amsmath} 6 | \usepackage{amssymb} 7 | \usepackage{multirow} 8 | \usepackage{hyperref} 9 | 10 | % Our style 11 | \usepackage{pseudo} 12 | 13 | \hbadness=10000 14 | 15 | %opening 16 | \title{Description of Algorithms used in Cashlib} 17 | %\author{Brownies} 18 | 19 | \begin{document} 20 | 21 | \maketitle 22 | 23 | %\begin{abstract} 24 | 25 | %\end{abstract} 26 | 27 | 28 | \newpage 29 | \tableofcontents 30 | \newpage 31 | 32 | \input{params} 33 | \input{assumptions} 34 | \input{setup} 35 | 36 | \section{Commitment Schemes} 37 | \input{fujisaki-okamoto} 38 | \input{pedersen} 39 | 40 | \input{hvzk} 41 | \input{dlr} 42 | \input{equality} 43 | \input{multiplication} 44 | \input{range} 45 | \input{special-range} 46 | 47 | \input{cl-signature} 48 | 49 | \section{E-cash} 50 | In this section, we provide a description of the offline versions of 51 | compact e-cash~\cite{chl:compact-ecash:ec05} and endorsed 52 | e-cash~\cite{clm:endorsed-ecash:ieee07}. We require that all connections 53 | between a user and the bank must be over an authenticated and secure channel 54 | (i.e., an SSL connection using the bank's certificate). 55 | \input{compact} 56 | \input{endorsed} 57 | 58 | 59 | \input{verifiable} 60 | 61 | \section{Fair Exchange} 62 | Use regular encryption, signatures, public-key encryption, e-cash and verifiable encryption to perform fair exchange. 63 | \input{buy} 64 | \subsection{Barter} 65 | \subsubsection{Alice} 66 | \subsubsection{Bob} 67 | \subsubsection{Arbiter} 68 | 69 | \appendix 70 | \input{appendix} 71 | 72 | \bibliographystyle{plain} 73 | \bibliography{sarah} 74 | 75 | \end{document} 76 | -------------------------------------------------------------------------------- /doc/pseudocodes/range.tex: -------------------------------------------------------------------------------- 1 | \subsection{Proof that a committed value lies within an interval [lo,hi]} 2 | 3 | We would like to prove that a secret value $x$ lies within a publicly known interval $[lo,hi]$, as in \cite{boudotInterval,lipmaaInterval}. The protocol uses a special RSA group. The verifier knows a commitment $C_x$ to $x$, and $lo,hi$, along with the RSA group definition. The prover additionally knows the secret $x$. 4 | 5 | Observe that $x$ is in the interval $[lo,hi]$ iff $x-lo \geq 0$ and $hi-x \geq 0$. Furthermore, any non-negative integer can be represented as a sum of 4 squares \cite{lipmaaInterval} (\eg $x-lo = v_{1}^{2} + v_{2}^{2} + v_{3}^{2} + v_{4}^{2}$), whereas negative integers cannot. These numbers ($v_i$) can be computed efficiently \cite{lipmaaInterval,rabinShallit}. Let $W_i$ be $v_{i}^{2}$. 6 | 7 | Further observe that a commitment to $x-lo$ can easily be obtained by computing $C_x g_{1}^{-lo}$, and a commitment to $hi-x$ can easily be obtained by computing $g_{1}^{hi} C_{x}^{-1}$. 8 | 9 | We have seen that using the Mult algorithm, we can prove that a committed number is actually a square. Therefore, the basic idea is to prove that each $W_i$ is a square (by committing to them so that the verifier does not learn $W_i$ or $v_i$), and then their sum is equal to $x-lo$. A similar proof also needs to be given for $hi-x$. 10 | 11 | We call this protocol \textbf{Range}. It uses Fujisaki-Okamoto commitments. Therefore it requires the same setup and the same assumptions. Everything said for the Fujisaki-Okamoto commitments also applies here. 12 | 13 | 14 | \textsc{Assumptions}:\\ 15 | The security of the scheme relies on Strong RSA assumption. 16 | 17 | 18 | \textsc{Honest-Verifier Zero Knowledge}:\\ 19 | The protocol is honest verifier zero knowledge provided that the Fujisaki-Okamoto commitment is hiding. This means that the RSA group must be generated by a trusted third party or it must be proven to the Prover that each $g_i,h$ generates $QR_n$. 20 | 21 | 22 | \textsc{Soundness}:\\ 23 | The extraction works under the Strong RSA assumption, which requires that the RSA group may NOT be generated by the Prover. 24 | \\ 25 | 26 | 27 | Below we provide the pseudocode for proving that a given value $y$ is non-negative ($\geq 0$). We call this protocol \textbf{Non-Negative}. Then, proving the interval means running this protocol twice, one for $x-lo$ and one for $hi-x$. 28 | 29 | In the Non-Negative protocol, the Prover is given a commitment $C_y$ and its opening $open_y = y,r_y$, and the group definition. The Verifier is given $C_y$ and the group definition. 30 | 31 | \begin{enumerate} 32 | \item The Prover computes $v_1,v_2,v_3,v_4$ using the four-squares algorithm \cite{lipmaaInterval,rabinShallit}. Let $W_i = v_{i}^{2}$. 33 | \item The Prover computes commitments $C_i$ to $W_i$ with their openings $open_i = W_i,r_i$, with the only rule that the last randomness is set to be $r_4 = r_y - (r_1+r_2+r_3)$. 34 | \item The Prover proves that each $C_i$ is a commitment to a square, using the special case of the Mult protocol. 35 | \item The Verifier, in addition to checking that each $C_i$ is a commitment to a square, checks if $C_y = \Pi_{i=1}^{4} C_i$. If all checks pass, the Verifier accepts, otherwise he rejects. 36 | \end{enumerate} 37 | 38 | -------------------------------------------------------------------------------- /doc/pseudocodes/special-range.tex: -------------------------------------------------------------------------------- 1 | \subsection{Proof that a committed value lies within an interval [mean-delta,mean+delta]} 2 | 3 | The range proof given by the Range protocol can be made almost twice as efficient if the interval we want to prove has a special type: $[mean-delta,mean+delta]$ \cite{chlCOMPACT}. Call this protocol \textbf{SpecialRange}, which should be used instead of Range whenever possible, even if not stated explicitly. Note that, $x$ is in that interval iff $lo^2 - (x-mean)^2 \geq 0$. As before, the interval (and hence $lo,hi$) are publicly known. Let $A = delta^2 - (x-mean)^2 = delta^2 - mean^2 + 2*mean*x - x^2$. 4 | 5 | For ease of notation, let $D = g_{1}^{delta^2 - mean^2}$, $E = (g_{1}^{2hi} C_{x}^{-1})$. A commitment $F$ to $A$ can be computed as $D * E^x * h^{r_A}$. Note that the Prover can compute this, but the Verifier can only compute $D$ and $E$. 6 | 7 | 8 | The Verifier knows a commitment $C_x$ to $x$, the interval (meaning $lo,hi$), and the RSA group definition, and can compute $D$ and $E$. The Prover, in addition to these, also knows the opening $open_x = x,r_x$ to $C_x$. 9 | 10 | 11 | \begin{enumerate} 12 | \item The Prover computes $F = D * E^x * h^{r_A} = g_{1}^{A} h^{r'_A}$ and proves that $F$ and $C_x$ are commitments to the same number under the bases $D,E,h$ and $1,g,h$ using the PoEoDLR protocol. 13 | \item The Prover runs the Non-Negative protocol for $A$ using $F$ as the commitment to $A$, where $r'_A = r_A - x r_x$. 14 | \end{enumerate} 15 | -------------------------------------------------------------------------------- /doc/usenix10.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brownie/cashlib/8820b953f8d0377c35dab909f60168370edce168/doc/usenix10.pdf -------------------------------------------------------------------------------- /src/.gitignore: -------------------------------------------------------------------------------- 1 | .deps 2 | test 3 | *.P 4 | *.o 5 | *.d 6 | *~ 7 | gmon.out 8 | brownieTest 9 | Serialize.h.gch 10 | zkptest 11 | libcash.a 12 | -------------------------------------------------------------------------------- /src/Arbiter.h: -------------------------------------------------------------------------------- 1 | #ifndef _ARBITER_H_ 2 | #define _ARBITER_H_ 3 | 4 | #include "MerkleProof.h" 5 | #include "VEDecrypter.h" 6 | #include "BuyMessage.h" 7 | #include "MerkleVerifier.h" 8 | #include "FEResolutionMessage.h" 9 | 10 | /*! \brief This class is for resolving any disputes that may arise in the 11 | * course of a fair exchange protocol */ 12 | 13 | typedef pair, BuyMessage*> ResolutionPair; 14 | 15 | class Arbiter { 16 | public: 17 | Arbiter(const VEDecrypter* vD, const VEDecrypter* rD, 18 | const hashalg_t &h, int t) 19 | : verifiableDecrypter(vD), regularDecrypter(rD), hashAlg(h), 20 | timeoutTolerance(t) {} 21 | 22 | /*! resolutions for buyer/initiator are the same: retrieve the 23 | * seller key(s) from the database if the id r exists as an entry */ 24 | vector buyerResolve(const ZZ &r); 25 | vector initiatorResolve(const ZZ &r); 26 | 27 | // the following are resolutions for the seller 28 | /*! first check the validity of the message, then output a set of 29 | * challenges */ 30 | vector sellerResolveI(const ResolutionPair &keyMessagePair); 31 | 32 | /*! if the proof verifies, output the buyer's endorsement and 33 | * store the seller's keys in the database (for the buyer to 34 | * retrieve at some later date) */ 35 | vector sellerResolveII(const MerkleProof* proof); 36 | 37 | // the following are resolutions for the responder 38 | /*! Stage I: the responder sends a request, and the arbiter 39 | * checks the validity of the two messages and stores the keys */ 40 | vector responderResolveI(const FEResolutionMessage* request); 41 | vector responderResolveI(const vector &keys, 42 | const FEMessage* message, 43 | const FESetupMessage* setupMessage); 44 | 45 | /*! Stage II: if the proof verifies, return the initiator's keys */ 46 | vector responderResolveII(const MerkleProof* proof); 47 | 48 | /*! Stage III: if the initiator's keys were incorrect, the responder 49 | * sends a proof of this. if this proof is valid the arbiter will 50 | * return the endorsement */ 51 | vector responderResolveIII(const MerkleProof* prooof); 52 | 53 | //used to test stuff 54 | void setKeys(const vector &ks){ keys = ks; } 55 | 56 | boost::function)> updateDB; 57 | boost::function(ZZ)> getDB; 58 | 59 | private: 60 | void updateDatabase(const ZZ &sessionID, const string &key); 61 | 62 | /*! takes in a proof and verifies it using the stored keys */ 63 | bool verifyKeys(const MerkleProof* proof); 64 | 65 | /*! much like verifyKeys except it ignores plaintext proofs; this 66 | * is a helper for responderResolveIII */ 67 | bool verifyDecryption(const MerkleProof* proof); 68 | 69 | const VEDecrypter* verifiableDecrypter;//, regularDecrypter; 70 | const VEDecrypter* regularDecrypter; 71 | hashalg_t hashAlg; 72 | int timeoutTolerance; 73 | boost::shared_ptr ptVerifier, ctVerifier; 74 | vector endorsement; 75 | vector keys; 76 | FEContract contract; 77 | const FEMessage* message; 78 | }; 79 | 80 | #endif 81 | -------------------------------------------------------------------------------- /src/Bank.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "Bank.h" 3 | 4 | ZZ Bank::randomNumber() { 5 | ZZ result = groupPrime->randomExponent(); 6 | while(result == 0) { 7 | result = groupPrime->randomExponent(); 8 | } 9 | return result; 10 | } 11 | 12 | ZZ Bank::fullCommitment(const ZZ &partial, const ZZ &bankPart) { 13 | ZZ g = groupPrime->getGenerator(0); 14 | ZZ mod = groupPrime->getModulus(); 15 | return MulMod(partial, PowerMod(g, bankPart, mod), mod); 16 | } 17 | -------------------------------------------------------------------------------- /src/Bank.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef _BANK_H_ 3 | #define _BANK_H_ 4 | 5 | #include "GroupPrime.h" 6 | #include "GroupRSA.h" 7 | 8 | class Bank { 9 | 10 | public: 11 | Bank(const GroupPrime* grpPrime, const GroupRSA* secret) 12 | : groupPrime(grpPrime), secretKey(secret) {} 13 | 14 | Bank(const Bank &o) 15 | : groupPrime(o.groupPrime), secretKey(o.secretKey) {} 16 | 17 | ~Bank() { delete groupPrime; delete secretKey; } 18 | 19 | /*! returns a random number from prime-order group */ 20 | ZZ randomNumber(); 21 | 22 | /*! on input a partial commitment A', outputs a full commitment A */ 23 | ZZ fullCommitment(const ZZ &part, const ZZ &bankPart); 24 | 25 | private: 26 | const GroupPrime* groupPrime; 27 | const GroupRSA* secretKey; 28 | }; 29 | 30 | #endif /*_BANK_H_*/ 31 | -------------------------------------------------------------------------------- /src/BankParameters.cpp: -------------------------------------------------------------------------------- 1 | #include "BankParameters.h" 2 | 3 | BankParameters::BankParameters(vector &secrets, GroupPrime &ecashGrp, 4 | vector &denoms) 5 | : coinDenominations(denoms) 6 | { 7 | ecashGroup = new GroupPrime(ecashGrp); 8 | type = BankParameters::TYPE_SECRET; 9 | for (unsigned i = 0; i < secrets.size(); i++) { 10 | secretKeys.push_back(new GroupRSA(secrets[i])); 11 | } 12 | 13 | // set up maps that associate a given key with a denomination 14 | for(unsigned i = 0; i < coinDenominations.size(); i++) { 15 | groupToDenom[secretKeys[i]] = coinDenominations[i]; 16 | denomToGroup[coinDenominations[i]] = secretKeys[i]; 17 | } 18 | } 19 | 20 | BankParameters::BankParameters(const BankParameters &o) 21 | : ecashGroup(new GroupPrime(*o.ecashGroup)), type(o.type), 22 | secretKeys(o.secretKeys), groupToDenom(o.groupToDenom), 23 | denomToGroup(o.denomToGroup), coinDenominations(o.coinDenominations) 24 | { 25 | } 26 | 27 | BankParameters::~BankParameters() { 28 | /*delete ecashGroup; 29 | for (unsigned i = 0 ; i < secretKeys.size() ; i++) { 30 | delete secretKeys[i]; 31 | } 32 | secretKeys.clear();*/ 33 | } 34 | 35 | const GroupRSA* BankParameters::getBankKey(int denomination) const { 36 | map::const_iterator i = denomToGroup.find(denomination); 37 | if (i == denomToGroup.end()) { 38 | throw CashException(CashException::CE_UNKNOWN_ERROR, 39 | "[BankParameters:getBankKey] Tried to find BankKey for " 40 | "number (%d) not associated with a denomination.", 41 | denomination); 42 | } 43 | return i->second; 44 | } 45 | 46 | int BankParameters::getCoinDenomination(GroupRSA* group) const { 47 | map::const_iterator i = groupToDenom.find(group); 48 | if (i == groupToDenom.end()) { 49 | throw CashException(CashException::CE_UNKNOWN_ERROR, 50 | "[BankParameters:getCoinDenomination] Tried to find denomination " 51 | "for group not associated with a denomination."); 52 | } 53 | return i->second; 54 | } 55 | 56 | void BankParameters::makePublic() { 57 | for(unsigned i = 0 ; i < secretKeys.size(); i++) { 58 | secretKeys[i]->clearSecrets(); 59 | } 60 | type = BankParameters::TYPE_PUBLIC; 61 | } 62 | 63 | -------------------------------------------------------------------------------- /src/BankParameters.h: -------------------------------------------------------------------------------- 1 | #ifndef _BANKPARAMETERS_H_ 2 | #define _BANKPARAMETERS_H_ 3 | 4 | #include "NTL/ZZ.h" 5 | #include "GroupPrime.h" 6 | #include "GroupRSA.h" 7 | #include 8 | 9 | /*! \brief This class is a container for the parameters created and 10 | * published by the Bank */ 11 | 12 | class BankParameters { 13 | 14 | public: 15 | /*! this class stores the bank's public keys, the group used 16 | * for e-cash, and a list of possible coin denominations */ 17 | BankParameters(vector &secretKey, GroupPrime &ecash, 18 | vector &denoms); 19 | 20 | /*! constructor to load from file */ 21 | BankParameters(const char* fname) 22 | { loadFile(make_nvp("BankParameters", *this), fname); } 23 | 24 | /*! copy constructor */ 25 | BankParameters(const BankParameters &original); 26 | 27 | /*! destructor */ 28 | ~BankParameters(); 29 | 30 | /*! determines whether RSA groups have had secrets cleared or not */ 31 | static const int TYPE_SECRET = 1; 32 | static const int TYPE_PUBLIC = 0; 33 | int getType() const { return type; } 34 | 35 | /*! getters */ 36 | const GroupPrime* getCashGroup() const { return ecashGroup; } 37 | const vector getBankKeys() const { return secretKeys; } 38 | vector getDenominations() const { return coinDenominations; } 39 | const GroupRSA* getBankKey(int coinDenomination) const; 40 | int getCoinDenomination(GroupRSA* group) const; 41 | 42 | /*! clear all secrets and set type to public */ 43 | void makePublic(); 44 | 45 | private: 46 | BankParameters() : ecashGroup(0), type(1) {} 47 | 48 | GroupPrime* ecashGroup; 49 | int type; 50 | vector secretKeys; 51 | // XXX: do we want this to be hardcoded? 52 | const static int stat = 80; 53 | map groupToDenom; 54 | map denomToGroup; 55 | vector coinDenominations; 56 | 57 | friend class boost::serialization::access; 58 | template 59 | void serialize(Archive& ar, const unsigned int ver) { 60 | ar & auto_nvp(type) // XXX save text of "public"/"secret"? 61 | // XXX stat? 62 | & auto_nvp(ecashGroup) 63 | & auto_nvp(secretKeys) 64 | & auto_nvp(groupToDenom) 65 | & auto_nvp(denomToGroup) 66 | & auto_nvp(coinDenominations); 67 | } 68 | }; 69 | 70 | #endif /*_BANKPARAMETERS_H_*/ 71 | -------------------------------------------------------------------------------- /src/BankTool.h: -------------------------------------------------------------------------------- 1 | #ifndef BANKTOOL_H_ 2 | #define BANKTOOL_H_ 3 | 4 | #include "SigmaProof.h" 5 | #include "BankWithdrawTool.h" 6 | #include "Wallet.h" 7 | #include "BankParameters.h" 8 | 9 | class BankTool { 10 | public: 11 | BankTool(int st, int l, int modLen, const hashalg_t &ha, 12 | vector &coinDenoms); 13 | 14 | BankTool(int st, int l, const hashalg_t &ha, 15 | BankParameters bp); 16 | 17 | BankTool(const BankTool &original); 18 | 19 | BankTool(const char *fname) 20 | : bankParameters(0), publicBankParameters(0) 21 | { loadFile(make_nvp("BankTool", *this), fname); } 22 | 23 | ~BankTool(); 24 | 25 | // getters 26 | const BankParameters* getBankParameters() const 27 | { return publicBankParameters; } 28 | const GroupPrime* getCashGroup() const 29 | { return publicBankParameters->getCashGroup(); } 30 | const vector getBankPublicKeys() const 31 | { return publicBankParameters->getBankKeys(); } 32 | const GroupRSA* getBankPublicKey(int denom) const 33 | { return publicBankParameters->getBankKey(denom); } 34 | 35 | /*! Inputs: user public key, group corresponding to public key, and 36 | * wallet size. 37 | * Output: a tool for interacting with a user who wants to withdraw a 38 | * wallet. 39 | * The BWTool returned must be freed by the caller. */ 40 | BankWithdrawTool* getWithdrawTool(const ZZ &userPK, int wSize, 41 | int coinDenom) const; 42 | 43 | /*! Input: a non interactive sigma proof of knowledge of a user's secret 44 | * key, using the public key as a commitment to the secret key. 45 | * Ouputs: true if proof accepted, false if proof not accepted. */ 46 | bool verifyIdentity(ProofMessage* idProof, const ZZ &userPK) const; 47 | 48 | // functions for depositing at the bank 49 | /*! Returns true if a coin is formed correctly */ 50 | bool verifyCoin(const Coin &coin) const; 51 | 52 | /*! Returns true if coin is double spent, false if merchant is just 53 | * trying to deposit twice. */ 54 | bool isCoinDoubleSpent(const Coin &coin, const Coin &coin2) const; 55 | 56 | /*! given coins that have been double-spent, identify the 57 | * public key of the user who withdrew the coins */ 58 | ZZ identifyDoubleSpender(const Coin& coin1, const Coin& coin2) const; 59 | ZZ identifyDoubleSpender(const Coin& coin1, const ZZ& t2, 60 | const ZZ& r2) const; 61 | 62 | private: 63 | int stat, lx; 64 | hashalg_t hashAlg; 65 | BankParameters* bankParameters; 66 | BankParameters* publicBankParameters; 67 | 68 | friend class boost::serialization::access; 69 | template 70 | void serialize(Archive& ar, const unsigned int ver) { 71 | ar & auto_nvp(stat) 72 | & auto_nvp(lx) 73 | & auto_nvp(hashAlg) 74 | // XXX also save public/private key files/params? 75 | & auto_nvp(bankParameters) 76 | & auto_nvp(publicBankParameters); 77 | } 78 | }; 79 | 80 | #endif // BANKTOOL_H_ 81 | -------------------------------------------------------------------------------- /src/BankWithdrawTool.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "BankWithdrawTool.h" 3 | #include "CashException.h" 4 | #include "CLBlindIssuer.h" 5 | 6 | BankWithdrawTool::BankWithdrawTool(const BankParameters *bp, const ZZ &userPK, 7 | int st, int l, int wSize, int denom, 8 | const hashalg_t &ha) 9 | : bankParameters(bp), userPublicKey(userPK), stat(st), lx(l), 10 | walletSize(wSize), coinDenom(denom), hashAlg(ha) 11 | { 12 | int allowedWalletSizes[] = {1,5,10,25,50,100,250,500,1000}; 13 | bool walletSizeValid = false; 14 | for (int i = 0; i < NUM_WALLET_SIZES; i++) { 15 | if (walletSize == allowedWalletSizes[i]) 16 | walletSizeValid = true; 17 | } 18 | if (!walletSizeValid) 19 | throw CashException(CashException::CE_SIZE_ERROR, 20 | "[BankWithdrawTool::BankWithdrawTool] invalid wallet size given"); 21 | } 22 | 23 | BankWithdrawTool::BankWithdrawTool(const BankWithdrawTool &o) 24 | : bankParameters(new BankParameters(*o.bankParameters)), 25 | userPublicKey(o.userPublicKey), stat(o.stat), lx(o.lx), 26 | walletSize(o.walletSize), coinDenom(o.coinDenom), 27 | bankContribution(o.bankContribution), hashAlg(o.hashAlg) 28 | { 29 | } 30 | 31 | void BankWithdrawTool::computeFullCommitment(const ZZ &partialCommitment) { 32 | ZZ g = bankParameters->getCashGroup()->getGenerator(0); 33 | ZZ mod = bankParameters->getCashGroup()->getModulus(); 34 | ZZ zero = to_ZZ(0); 35 | while(bankContribution == zero) { 36 | bankContribution = bankParameters->getCashGroup()->randomExponent(); 37 | } 38 | ZZ partialBase = PowerMod(g, bankContribution, mod); 39 | ZZ resultA = MulMod(partialCommitment, partialBase, mod); 40 | fullCommitment = resultA; 41 | } 42 | 43 | ProofMessage* BankWithdrawTool::sign(ProofMessage* id, ProofMessage* cl){ 44 | // first verify ID proof, then create issuer for the CL part 45 | InterpreterVerifier verifier; 46 | group_map g; 47 | g["cashGroup"] = bankParameters->getCashGroup(); 48 | verifier.check(CommonFunctions::getZKPDir()+"/presig.txt", g); 49 | variable_map v; 50 | v["pk_u"] = userPublicKey; 51 | verifier.compute(v, id->publics); 52 | bool idVerified = verifier.verify(id->proof, stat); 53 | if (!idVerified) { 54 | throw CashException(CashException::CE_UNKNOWN_ERROR, 55 | "[BankWithdrawTool::sign] Proof of ID did not verify"); 56 | } 57 | variable_map clPubs = cl->publics; 58 | const GroupRSA* sk = bankParameters->getBankKey(coinDenom); 59 | const GroupPrime* comGroup = bankParameters->getCashGroup(); 60 | vector coms; 61 | for (int i = 0; i < 3; i++) { 62 | string name = "c_"+lexical_cast(i+1); 63 | coms.push_back(clPubs.at(name)); 64 | } 65 | 66 | CLBlindIssuer issuer(sk, comGroup, lx, coms, 3, 1); 67 | vector publicMsg; 68 | publicMsg.push_back(to_ZZ(walletSize)); 69 | ZZ C = cl->vars.at("C"); 70 | return issuer.getPartialSignature(C, publicMsg, *cl, stat, hashAlg); 71 | } 72 | -------------------------------------------------------------------------------- /src/BankWithdrawTool.h: -------------------------------------------------------------------------------- 1 | #ifndef BANKWITHDRAWTOOL_H_ 2 | #define BANKWITHDRAWTOOL_H_ 3 | 4 | #include "BankParameters.h" 5 | #include "ZKP/Environment.h" 6 | 7 | class BankWithdrawTool { 8 | public: 9 | BankWithdrawTool(const BankParameters *bp, const ZZ &userPK, 10 | int stat, int lx, int wSize, int denom, 11 | const hashalg_t &hashAlg); 12 | 13 | BankWithdrawTool(const BankWithdrawTool &original); 14 | 15 | // computes and stores random number from Z*_primeOrder 16 | ZZ getBankContribution() { return bankContribution; } 17 | 18 | // input: a commitment to s' 19 | // output: A commitment to s = s' + r' 20 | // r' is the bank's contribution of randomness 21 | void computeFullCommitment(const ZZ &partialCommitment); 22 | 23 | // This method will return the bank's signature if the sigma proofs 24 | // are verified, and will throw exceptions if they are not verified 25 | ProofMessage* sign(ProofMessage* id, ProofMessage* cl); 26 | 27 | int getWalletSize() const { return walletSize; } 28 | int getDenom() const { return coinDenom; } 29 | 30 | private: 31 | const BankParameters* bankParameters; 32 | ZZ userPublicKey; 33 | int stat, lx, walletSize, coinDenom; 34 | ZZ bankContribution; 35 | hashalg_t hashAlg; 36 | 37 | // the full commitment to s = s' + r' which is computed in 38 | // getFullCommitment(partialCommitment) 39 | ZZ fullCommitment; 40 | }; 41 | 42 | #define NUM_WALLET_SIZES 7 43 | 44 | 45 | #endif // BANKWITHDRAWTOOL_H_ 46 | -------------------------------------------------------------------------------- /src/BuyMessage.cpp: -------------------------------------------------------------------------------- 1 | #include "BuyMessage.h" 2 | #include "VEVerifier.h" 3 | #include "Timer.h" 4 | 5 | bool BuyMessage::check(const VEPublicKey* pk, const int stat, 6 | const ZZ& R) const { 7 | // check coin 8 | if (!coinPrime.verifyCoin() || coinPrime.getR() != R) 9 | throw CashException(CashException::CE_FE_ERROR, 10 | "[BuyMessage::check] Malformed coin"); 11 | 12 | // check verifiable escrow 13 | startTimer(); 14 | VEVerifier verifier(pk); 15 | if (!verifier.verify(*escrow, coinPrime.getEndorsementCom(), 16 | coinPrime.getCashGroup(), saveString(contract), 17 | pk->hashAlg, stat)) 18 | throw CashException(CashException::CE_FE_ERROR, 19 | "[BuyMessage::check] Malformed escrow"); 20 | printTimer("[Seller] checked verifiable escrow"); 21 | return true; 22 | } 23 | -------------------------------------------------------------------------------- /src/BuyMessage.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef _BUYMESSAGE_H_ 3 | #define _BUYMESSAGE_H_ 4 | 5 | #include "Coin.h" 6 | #include "FEContract.h" 7 | #include "VECiphertext.h" 8 | #include "VEPublicKey.h" 9 | 10 | /*! \brief This class is just a container for the message sent by the 11 | * Buyer in the buy protocol - it contains the unendorsed coin and the 12 | * escrow of the endorsement for the coin */ 13 | 14 | class BuyMessage { 15 | public: 16 | /*! coinPrime represents the unendorsed coin, contract represents 17 | * the label for the verifiable encryption, and escrow represents 18 | * the verifiable escrow on the coin's endorsement */ 19 | BuyMessage(const Coin &coinPrime, FEContract* contract, 20 | VECiphertext* escrow) 21 | : coinPrime(coinPrime), contract(contract), escrow(escrow) {} 22 | 23 | /*! copy constructor */ 24 | BuyMessage(const BuyMessage &o) 25 | : coinPrime(o.coinPrime), contract(o.contract), escrow(o.escrow) {} 26 | 27 | ~BuyMessage() { /*delete contract;*/ delete escrow; } 28 | 29 | BuyMessage(const string& s, const BankParameters *params) { 30 | // need to set params for Coin contained in message 31 | loadGZString(make_nvp("BuyMessage", *this), s); 32 | coinPrime.setParameters(params); 33 | } 34 | 35 | /*! check contents (verify coin and escrow) */ 36 | bool check(const VEPublicKey* pk, const int stat, const ZZ& R) const; 37 | 38 | // getters 39 | Coin getCoinPrime() const { return coinPrime; } 40 | FEContract* getContract() const { return contract; } 41 | VECiphertext* getEscrow() const { return escrow; } 42 | 43 | private: 44 | Coin coinPrime; 45 | FEContract* contract; 46 | VECiphertext* escrow; 47 | 48 | friend class boost::serialization::access; 49 | template 50 | void serialize(Archive& ar, const unsigned int ver) { 51 | ar & auto_nvp(coinPrime) 52 | & auto_nvp(contract) 53 | & auto_nvp(escrow); 54 | } 55 | }; 56 | 57 | #endif /*BUYMESSAGE_H_*/ 58 | -------------------------------------------------------------------------------- /src/Buyer.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef _BUYER_H_ 3 | #define _BUYER_H_ 4 | 5 | #include "Wallet.h" 6 | #include "VEPublicKey.h" 7 | #include "BuyMessage.h" 8 | #include "Ciphertext.h" 9 | #include "FESetupMessage.h" 10 | 11 | class Buyer { 12 | public: 13 | /*! constructor takes in various parameters, a wallet, and the 14 | * arbiter's public key */ 15 | Buyer(int timeoutLength, const VEPublicKey* pk, int stat); 16 | 17 | /*! copy constructor */ 18 | Buyer(const Buyer &o); 19 | 20 | /*! destructor */ 21 | ~Buyer(); 22 | 23 | /*! buy the ciphertext by sending an unendorsed coin, 24 | * a verifiable escrow of the endorsement, and associated 25 | * contract */ 26 | BuyMessage* buy(Wallet* wallet, EncBuffer* ctext, 27 | const hash_t& ptHash, const ZZ &R); 28 | 29 | /*! buy multiple files */ 30 | BuyMessage* buy(Wallet* wallet, const vector& ctext, 31 | const vector& ptHash, const ZZ &R); 32 | 33 | /*! assumes setCoin() has been called */ 34 | BuyMessage* buy(EncBuffer* ctext, const hash_t& ptHash); 35 | 36 | /*! assumes setCoin() has been called */ 37 | BuyMessage* buy(const vector& ctext, 38 | const vector& ptHash); 39 | 40 | 41 | 42 | /*! pay the seller with the endorsement if the key 43 | * given by the seller is correct 44 | * use same key for multiple ciphertexts 45 | * if given just one key but multiple ciphertexts */ 46 | vector pay(const string &key); 47 | vector pay(const vector& keys); 48 | bool checkKey(const vector& keys); 49 | 50 | 51 | /*! outputs the random r used for the sessson ID */ 52 | ZZ resolve(); 53 | 54 | 55 | /*! get the plaintext (if stored as string in Buyer) */ 56 | //string getFile() const { return *ptext; } 57 | const vector& getPtext() const { return ptext; } 58 | 59 | /*! get the endorsement (send after key is checked) */ 60 | const vector& getEndorsement() const { return endorsement; } 61 | 62 | bool canAbortLocally() {return !inProgress; }; 63 | 64 | // setters 65 | void setCoin(const Coin& coin); 66 | void setTimeout() { timeout =time(NULL) + timeoutLength; } 67 | void setSecurity(const int newstat) {stat = newstat;} 68 | void setVEPublicKey(const VEPublicKey* newpk) {pk = newpk;} 69 | 70 | void reset(); 71 | 72 | protected: 73 | void createContract(); 74 | void makeCoin(Wallet& w, const ZZ& R); 75 | VECiphertext makeEscrow(); 76 | 77 | private: 78 | int timeout; 79 | int timeoutLength; 80 | int stat; 81 | const VEPublicKey* pk; 82 | 83 | Coin coin; 84 | FEContract* contract; 85 | 86 | // ciphertext to decrypt, received from Seller 87 | vector ctext; 88 | // saves output of decrypt() if Buy protocol is successful 89 | vector ptext; 90 | 91 | ZZ r; 92 | vector endorsement; 93 | bool inProgress; 94 | }; 95 | 96 | #endif /*BUYER_H_*/ 97 | -------------------------------------------------------------------------------- /src/CLBlindIssuer.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef _CLBLINDISSUER_H_ 3 | #define _CLBLINDISSUER_H_ 4 | 5 | #include "GroupRSA.h" 6 | #include "ZKP/InterpreterVerifier.h" 7 | #include "ProgramMaker.h" 8 | 9 | class CLBlindIssuer { 10 | 11 | public: 12 | CLBlindIssuer(const GroupRSA* sk, const Group* comGroup, int lx, 13 | const vector &coms, int numPrivates, int numPublics); 14 | 15 | CLBlindIssuer(const GroupRSA* sk, int lx, int numPrivates, 16 | int numPublics, const gen_group_map &groups, 17 | const vector &coms); 18 | 19 | CLBlindIssuer(const CLBlindIssuer &o); 20 | 21 | /*! returns a variable map with the components of a partial signature 22 | * A, e, and v'' as well as a proof that it was correctly formed */ 23 | ProofMessage* getPartialSignature(const ZZ &C, const vector& pubs, 24 | const ProofMessage &pm, int stat, 25 | const hashalg_t &hashAlg); 26 | 27 | private: 28 | input_map inputs; 29 | group_map g; 30 | int numPrivates; 31 | int numPublics; 32 | variable_map v; 33 | InterpreterVerifier verifier; 34 | }; 35 | 36 | #endif /*_CLBLINDISSUER_H_*/ 37 | -------------------------------------------------------------------------------- /src/CLBlindRecipient.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef _CLBLINDRECIPIENT_H_ 3 | #define _CLBLINDRECIPIENT_H_ 4 | 5 | #include "GroupRSA.h" 6 | #include "ZKP/InterpreterProver.h" 7 | #include "ProgramMaker.h" 8 | 9 | class CLBlindRecipient { 10 | 11 | public: 12 | /*! this constructor assumes commitments are formed in e-cash group 13 | * and is passed in the number of private and public variables and 14 | * a message length parameter, as well as the private commitments */ 15 | CLBlindRecipient(const GroupRSA* pk, const Group* comGroup, int lx, 16 | const vector &coms, int numPrivates, 17 | int numPublics); 18 | 19 | /*! this constructor allows for commitments that have been formed in 20 | * groups other than the PK group */ 21 | CLBlindRecipient(const GroupRSA* pk, int lx, int numPrivates, 22 | int numPublics, const gen_group_map &groups, 23 | const vector &coms); 24 | 25 | // XXX: right now we're assuming that each private message is 26 | // committed to individually... we shouldn't be doing this, because 27 | // it is also possible to use one that is a commitment to all at once 28 | /*! returns the product C = h^v' * g_1^x_1 * ... * g_l^x_l, as 29 | * well as a proof that it was formed correctly */ 30 | ProofMessage* getC(const vector &privates, 31 | const hashalg_t &hashAlg); 32 | 33 | /*! given a partial signature, check that it was formed 34 | * correctly (i.e. that bank's PoK of 1/e verifies) */ 35 | bool verifySig(const ProofMessage &pm, int stat); 36 | 37 | /*! given a partial signature, creates the full signature (A, e, v) */ 38 | vector createSig(const vector &partialSig); 39 | 40 | private: 41 | group_map g; 42 | variable_map v; 43 | input_map inputs; 44 | InterpreterProver prover; 45 | int numPrivates; 46 | int numPublics; 47 | }; 48 | 49 | #endif /*_CLBLINDRECIPIENT_H_*/ 50 | -------------------------------------------------------------------------------- /src/CLSignatureProver.cpp: -------------------------------------------------------------------------------- 1 | #include "CLSignatureProver.h" 2 | #include 3 | #include "Timer.h" 4 | 5 | CLSignatureProver::CLSignatureProver(const GroupRSA* publicKey, 6 | const Group* comGroup, int lx, 7 | const vector &coms, int numPrivates, 8 | int numPublics) 9 | :numPrivates(numPrivates), numPublics(numPublics) 10 | { 11 | //setting up maps 12 | g["pkGroup"] = publicKey; 13 | g["comGroup"] = comGroup; 14 | v["stat"] = publicKey-> getStat(); 15 | v["l_x"] = lx; 16 | v["modSize"] = publicKey->getModulusLength(); 17 | assert((int)coms.size() == numPrivates); 18 | for (unsigned i = 0; i < coms.size(); i++) { 19 | v["c_"+lexical_cast(i+1)] = coms[i]; 20 | } 21 | 22 | inputs["l"] = numPrivates; 23 | inputs["k"] = numPublics; 24 | prover.check(CommonFunctions::getZKPDir()+"/cl-prove-ecash.txt", inputs, g); 25 | } 26 | 27 | CLSignatureProver::CLSignatureProver(const GroupRSA* pk, int lx, 28 | int numPrivates, int numPublics, 29 | const gen_group_map &grps, 30 | const vector &coms) 31 | : numPrivates(numPrivates), numPublics(numPublics) 32 | { 33 | v["modSize"] = pk->getModulusLength(); 34 | v["l_x"] = lx; 35 | v["stat"] = pk->getStat(); 36 | vector genNames; 37 | genNames.push_back("f"); 38 | for (int i = 0; i < numPrivates+numPublics; i++) { 39 | genNames.push_back("g_"+lexical_cast(i+1)); 40 | } 41 | genNames.push_back("h"); 42 | gen_group_map pMap(grps); 43 | pMap["pkGroup"] = make_pair(pk, genNames); 44 | for (gen_group_map::iterator it = pMap.begin(); it != pMap.end(); ++it) { 45 | g[it->first] = it->second.first; 46 | } 47 | // insert commitments 48 | for (unsigned i = 0; i < coms.size(); i++) { 49 | v["c_"+lexical_cast(i+1)] = coms[i].comValue; 50 | } 51 | string fname = ProgramMaker::makeCLProve(pMap, coms); 52 | inputs["l"] = numPrivates; 53 | inputs["k"] = numPublics; 54 | prover.check(fname, inputs, g); 55 | } 56 | 57 | ProofMessage* CLSignatureProver::getProof(const vector& sig, 58 | const vector& privates, 59 | const vector& publics, 60 | const hashalg_t &hashAlg){ 61 | if((int)publics.size()!=numPublics) 62 | throw CashException(CashException::CE_SIZE_ERROR, 63 | "[CLSignatureProver::getC] Number of public inputs does not " 64 | "match the number the issuer was constructed with"); 65 | 66 | if((int)privates.size()!=numPrivates) 67 | throw CashException(CashException::CE_SIZE_ERROR, 68 | "[CLSignatureProver::getC] Number of private inputs does not " 69 | "match the number the recipient was constructed with"); 70 | 71 | // set up proving environment 72 | // XXX: need to check that all the public values are in the 73 | // proper range, don't we? 74 | for(unsigned i = 0; i < publics.size(); i++) 75 | v["x_"+lexical_cast(i+numPrivates+1)] = publics[i]; 76 | 77 | for(unsigned i = 0; i < privates.size(); i++) { 78 | v["x_"+lexical_cast(i+1)] = privates[i].first; 79 | v["r_"+lexical_cast(i+1)] = privates[i].second; 80 | } 81 | 82 | v["A"] = sig[0]; 83 | v["e"] = sig[1]; 84 | v["v"] = sig[2]; 85 | startTimer(); 86 | prover.compute(v); 87 | printTimer("CL prover computed all values"); 88 | return new ProofMessage(prover.getPublicVariables(), 89 | prover.computeProof(hashAlg)); 90 | } 91 | 92 | -------------------------------------------------------------------------------- /src/CLSignatureProver.h: -------------------------------------------------------------------------------- 1 | #ifndef CLSIGNATUREPROVER_H_ 2 | #define CLSIGNATUREPROVER_H_ 3 | 4 | #include "GroupRSA.h" 5 | #include "ProgramMaker.h" 6 | #include "ZKP/InterpreterProver.h" 7 | 8 | class CLSignatureProver { 9 | public: 10 | /*! this constructor assumes all operations take place in the same 11 | * group */ 12 | CLSignatureProver(const GroupRSA *publicKey, const Group* comGroup, 13 | int lx, const vector &coms, int numPrivates, 14 | int numPublics); 15 | 16 | CLSignatureProver(const GroupRSA* pk, int lx, int numPrivates, 17 | int numPublics, const gen_group_map &grps, 18 | const vector &coms); 19 | 20 | /*! returns SigmaProof of valid signature */ 21 | ProofMessage* getProof(const vector& sig, 22 | const vector& privates, 23 | const vector& publics, 24 | const hashalg_t &hashAlg); 25 | 26 | private: 27 | group_map g; 28 | input_map inputs; 29 | int numPrivates; 30 | int numPublics; 31 | variable_map v; 32 | InterpreterProver prover; 33 | }; 34 | 35 | #endif 36 | -------------------------------------------------------------------------------- /src/CLSignatureVerifier.cpp: -------------------------------------------------------------------------------- 1 | #include "CLSignatureVerifier.h" 2 | 3 | CLSignatureVerifier::CLSignatureVerifier(const GroupRSA* publicKey, 4 | const Group* comGroup, int lx, 5 | const vector &coms, 6 | int numPrivates, int numPublics) 7 | : numPrivates(numPrivates), numPublics(numPublics) 8 | { 9 | //setting up group and input maps for constant substitution 10 | g["pkGroup"] = publicKey; 11 | g["comGroup"] = comGroup; 12 | v["stat"] = publicKey-> getStat(); 13 | v["l_x"] = lx; 14 | v["modSize"] = publicKey->getModulusLength(); 15 | for (unsigned i = 0; i < coms.size(); i++) { 16 | v["c_"+lexical_cast(i+1)] = coms[i]; 17 | } 18 | inputs["l"] = numPrivates; 19 | inputs["k"] = numPublics; 20 | verifier.check(CommonFunctions::getZKPDir()+"/cl-prove-ecash.txt", inputs); 21 | } 22 | 23 | CLSignatureVerifier::CLSignatureVerifier(const GroupRSA* pk, int lx, 24 | int numPrivates, int numPublics, 25 | const gen_group_map &groups, 26 | const vector &coms) 27 | : numPrivates(numPrivates), numPublics(numPublics) 28 | { 29 | inputs["l"] = numPrivates; 30 | inputs["k"] = numPublics; 31 | v["l_x"] = lx; 32 | v["stat"] = pk->getStat(); 33 | v["modSize"] = pk->getModulusLength(); 34 | gen_group_map pMap(groups); 35 | vector genNames; 36 | genNames.push_back("f"); 37 | for (int i = 0; i < numPrivates + numPublics; i++) { 38 | genNames.push_back("g_"+lexical_cast(i+1)); 39 | } 40 | genNames.push_back("h"); 41 | pMap["pkGroup"] = make_pair(pk, genNames); 42 | for (gen_group_map::iterator it = pMap.begin(); it != pMap.end(); ++it) { 43 | g[it->first] = it->second.first; 44 | } 45 | for (unsigned i = 0; i < coms.size(); i++) { 46 | v["c_"+lexical_cast(i+1)] = coms[i].comValue; 47 | } 48 | string fname = ProgramMaker::makeCLProve(pMap, coms); 49 | verifier.check(fname, inputs); 50 | } 51 | 52 | bool CLSignatureVerifier::verify(const ProofMessage* pm, int stat) { 53 | SigmaProof proof = pm->proof; 54 | variable_map publics1 = pm->proof.getCommitments(); 55 | variable_map publics2 = pm->publics; 56 | verifier.compute(v, publics1, publics2, g); 57 | return verifier.verify(proof, stat); 58 | } 59 | 60 | -------------------------------------------------------------------------------- /src/CLSignatureVerifier.h: -------------------------------------------------------------------------------- 1 | #ifndef _CLSIGNATUREVERIFIER_H_ 2 | #define _CLSIGNATUREVERIFIER_H_ 3 | 4 | #include "GroupRSA.h" 5 | #include "ProgramMaker.h" 6 | #include "ZKP/InterpreterVerifier.h" 7 | 8 | class CLSignatureVerifier { 9 | public: 10 | CLSignatureVerifier(const GroupRSA *publicKey, 11 | const Group* comGroup, int lx, const vector &c, 12 | int numPrivates, int numPublics); 13 | 14 | CLSignatureVerifier(const GroupRSA* pk, int lx, int numPrivates, 15 | int numPublics, const gen_group_map &groups, 16 | const vector &coms); 17 | 18 | /*! checks to see if a signature composed of A, e, and v is valid */ 19 | bool verify(const ProofMessage* pm, int stat); 20 | 21 | private: 22 | group_map g; 23 | variable_map v; 24 | input_map inputs; 25 | int numPrivates; 26 | int numPublics; 27 | InterpreterVerifier verifier; 28 | }; 29 | 30 | #endif /*_CLSIGNATUREVERIFIER_H_*/ 31 | -------------------------------------------------------------------------------- /src/CashException.cpp: -------------------------------------------------------------------------------- 1 | #include "CashException.h" 2 | #include 3 | #include 4 | 5 | namespace { 6 | struct _init_openssl_errors { 7 | _init_openssl_errors() { ERR_load_crypto_strings(); } 8 | ~_init_openssl_errors() { ERR_free_strings(); } 9 | } _initerrors; 10 | } 11 | 12 | CashException::CashException() throw () 13 | : errorCode(-1), description() 14 | { 15 | } 16 | 17 | CashException::CashException(const CashException &original) throw () 18 | : exception(original), errorCode(original.errorCode) 19 | { 20 | description = original.description; 21 | } 22 | 23 | CashException::CashException(int ecode) throw () 24 | : errorCode(ecode), description() 25 | { 26 | if (ecode == CE_OPENSSL_ERROR) description += getOpenSSLError(); 27 | } 28 | 29 | CashException::CashException(int ecode, string &explanation) throw () 30 | : errorCode(ecode), description(explanation) 31 | { 32 | if (ecode == CE_OPENSSL_ERROR) description += getOpenSSLError(); 33 | } 34 | 35 | CashException::CashException(int ecode, const char *fmt, ...) throw () 36 | : errorCode(ecode) 37 | { 38 | char buf[FMTBUF_LEN]; 39 | va_list args; 40 | va_start(args, fmt); 41 | vsnprintf(buf, FMTBUF_LEN, fmt, args); 42 | va_end(args); 43 | 44 | description = string(buf); 45 | if (ecode == CE_OPENSSL_ERROR) description += "\n[OpenSSL err] " + getOpenSSLError(); 46 | } 47 | 48 | 49 | CashException::~CashException() throw () 50 | { 51 | } 52 | 53 | string CashException::getOpenSSLError() { 54 | char buffer[1024]; 55 | BIO *bio = BIO_new(BIO_s_mem()); 56 | ERR_print_errors(bio); 57 | ERR_clear_error(); 58 | (void)BIO_flush(bio); 59 | 60 | int len = BIO_gets(bio, buffer, 1024); 61 | (void)BIO_set_close(bio, BIO_NOCLOSE); 62 | BIO_free(bio); 63 | 64 | if (len < 0) { 65 | return "CashException::getOpenSSLError: can't read error"; 66 | } 67 | 68 | return string(buffer, len); 69 | } 70 | 71 | int CashException::getErrorCode() const throw () { 72 | return errorCode; 73 | } 74 | 75 | const char *CashException::what() const throw () { 76 | if (description.size()) 77 | return description.c_str(); 78 | 79 | // OK -- no description -- just go by what the error code says 80 | switch (errorCode) 81 | { 82 | case CashException::CE_NO_ERROR: 83 | return "No error. Not sure why we threw an exception."; 84 | case CashException::CE_UNKNOWN_ERROR: 85 | return "Unknown error"; 86 | case CashException::CE_SECURITY_ERROR: 87 | return "Security input parameter error"; 88 | case CashException::CE_SIZE_ERROR: 89 | return "Size error"; 90 | default: 91 | return "Illegal error code"; 92 | } 93 | } 94 | 95 | -------------------------------------------------------------------------------- /src/CashException.h: -------------------------------------------------------------------------------- 1 | #ifndef CASHEXCEPTION_H_ 2 | #define CASHEXCEPTION_H_ 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | using namespace std; 12 | 13 | class CashException : public exception 14 | { 15 | public: 16 | CashException() throw (); 17 | CashException(const CashException &e) throw (); 18 | CashException(int ecode) throw (); 19 | /*! create CashException with printf()-like format string */ 20 | CashException(int ecode, const char *fmt, ...) throw (); 21 | CashException(int ecode, string &explanation) throw (); 22 | static const int FMTBUF_LEN = 4096; 23 | 24 | virtual ~CashException() throw (); 25 | 26 | int getErrorCode() const throw (); 27 | virtual const char *what() const throw (); 28 | 29 | static string getOpenSSLError(); 30 | 31 | // a list of error codes 32 | static const int CE_NO_ERROR = 0; // No error 33 | static const int CE_UNKNOWN_ERROR = -1; // Unknown error 34 | static const int CE_SECURITY_ERROR = -2; // Problem w/ security params 35 | static const int CE_SIZE_ERROR = -3; // Problem w/ vector/array sizes 36 | static const int CE_IO_ERROR = -4; // Problem w/ input/output 37 | static const int CE_FE_ERROR = -5; // Problem w/ fair exchange 38 | static const int CE_HASH_ERROR = -6; // Problem w/ hashes 39 | static const int CE_OPENSSL_ERROR = -7; // Problem w/ OpenSSL 40 | static const int CE_TIMER_ERROR = -8; // Problem w/ Timer 41 | static const int CE_PARSE_ERROR = -9; // Problem w/ parsing 42 | static const int CE_NTL_ERROR = -10; // Problem w/ NTL 43 | 44 | private: 45 | int errorCode; 46 | string description; 47 | 48 | }; 49 | 50 | #endif 51 | -------------------------------------------------------------------------------- /src/CommonFunctions.h: -------------------------------------------------------------------------------- 1 | /*! 2 | * \brief This is a class designed to hold some common static functions that 3 | * can be used in multiple parts of the library. 4 | */ 5 | 6 | #ifndef COMMONFUNCTIONS_H_ 7 | #define COMMONFUNCTIONS_H_ 8 | 9 | #include "Group.h" 10 | 11 | class CommonFunctions { 12 | 13 | public: 14 | static string getZKPDir(); 15 | static void setZKPDir(const string&); 16 | 17 | static bool isTTP(const string &name); 18 | 19 | static string vecToBytes(const vector& vec) { 20 | size_t sz = 0; 21 | for (unsigned i=0; i < vec.size(); i++) 22 | sz += NTL::NumBytes(vec[i]); 23 | unsigned char buf[sz]; 24 | unsigned pos = 0; 25 | for (unsigned i=0; i < vec.size(); i++) { 26 | size_t n = NTL::NumBytes(vec[i]); 27 | NTL::BytesFromZZ((unsigned char *)buf + pos, vec[i], n); 28 | pos += n; 29 | } 30 | assert(pos == sz); 31 | return string((char *)&buf, sz); 32 | } 33 | 34 | static string vecToString(const vector &vec) { 35 | ostringstream out; 36 | for (unsigned i = 0; i < vec.size(); i++) { 37 | out << vec[i]; 38 | } 39 | return out.str(); 40 | } 41 | 42 | /** 43 | * Decomposing a positive integer into a sum of four squares 44 | * sub functions: decompose a prime into two squares 45 | * compute jacobi symbol 46 | * find integer square root 47 | * algorithm obtained from http://www.schorn.ch/howto.html 48 | * which looks like a somewhat reputable source. 49 | * has an acm email address, papers published, explanantion of alg. 50 | */ 51 | 52 | // p is prime and p = 1 mod 4 53 | static vector decomposePrime(const ZZ &p, int stat); 54 | 55 | // I found python decompose int code. 56 | // This method will attempt to use that program. 57 | static vector decompose(const ZZ &a); 58 | 59 | /*! returns part of vec from start to length-1 */ 60 | static vector subvector(const vector &vec, unsigned start, 61 | unsigned length); 62 | 63 | // absolute value function for Camenisch-Shoup verifiable encryption 64 | static ZZ abs(const ZZ& x, const ZZ& bigNsquared); 65 | 66 | template 67 | static vector vectorize(const T& element) 68 | { vector vec(1, element); return vec;} 69 | }; 70 | 71 | #endif /*COMMONFUNCTIONS_H_*/ 72 | -------------------------------------------------------------------------------- /src/Debug.h: -------------------------------------------------------------------------------- 1 | /* 2 | * File: Debug.h 3 | * Author: kupcu 4 | * 5 | * Created on October 5, 2008, 2:40 PM 6 | */ 7 | 8 | #ifndef _DEBUG_H 9 | #define _DEBUG_H 10 | 11 | #include "CommonFunctions.h" 12 | #include 13 | 14 | //#define DEBUG 15 | #define TIMER 16 | 17 | namespace __gnu_cxx { 18 | template<> struct hash { 19 | size_t operator()(const std::string &s) const { 20 | return hash()(s.c_str()); 21 | }; 22 | }; 23 | 24 | template<> struct hash< std::pair > { 25 | size_t operator()(const std::pair &p) const { 26 | return hash()((p.first + boost::lexical_cast(p.second)).c_str()); 27 | }; 28 | }; 29 | }; 30 | 31 | #endif /* _DEBUG_H */ 32 | 33 | -------------------------------------------------------------------------------- /src/FEContract.cpp: -------------------------------------------------------------------------------- 1 | #include "FEContract.h" 2 | #include "CashException.h" 3 | #include "CommonFunctions.h" 4 | 5 | bool FEContract::checkTimeout(int timeoutTolerance) const { 6 | int timeNow = time(NULL); 7 | // check timeout 8 | if (timeNow - timeoutTolerance > timeout) 9 | throw CashException(CashException::CE_FE_ERROR, 10 | "[FEContract::checkTimeout] Malformed contract (timeout is not " 11 | "tolerable)"); 12 | return true; 13 | } 14 | 15 | bool FEContract::checkEncAlgB(const cipher_t& encAlgR) const { 16 | if(encAlgB != encAlgR) 17 | throw CashException(CashException::CE_FE_ERROR, 18 | "[FEContract::checkEncAlgB] Malformed contract (responder encryption algorithm %s does not match %s)", encAlgR.c_str(), encAlgB.c_str()); 19 | return true; 20 | } 21 | 22 | 23 | bool FEContract::checkAFiles(const vector& ptext, 24 | const vector& ctext) const { 25 | return checkHashes(ptext, ctext, ptHashA, ctHashA); 26 | } 27 | 28 | bool FEContract::checkBFiles(const vector& ptext, 29 | const vector& ctext) const { 30 | return checkHashes(ptext, ctext, ptHashB, ctHashB); 31 | } 32 | 33 | bool FEContract::checkAFile(const Buffer* ptext, 34 | /*const*/ EncBuffer* ctext) const { 35 | return checkAFiles(CommonFunctions::vectorize(ptext), 36 | CommonFunctions::vectorize(ctext)); 37 | } 38 | 39 | bool FEContract::checkBFile(const Buffer* ptext, 40 | /*const*/ EncBuffer* ctext) const { 41 | return checkBFiles(CommonFunctions::vectorize(ptext), 42 | CommonFunctions::vectorize(ctext)); 43 | } 44 | 45 | bool FEContract::checkHashes(const vector& ptext, 46 | const vector& ctext, 47 | const hash_t& ptHash, const hash_t& ctHash) const { 48 | if (ptext.size() != ctext.size()) 49 | throw CashException(CashException::CE_FE_ERROR, 50 | "[FEContract::checkHashes] Malformed contract (number of files and " 51 | "ciphertexts mismatch)"); 52 | 53 | hash_t hash = Hash::hash(ptext, ptHash.alg, ptHash.key, ptHash.type); 54 | if (ptHash != hash) 55 | throw CashException(CashException::CE_FE_ERROR, 56 | "[FEContract::checkHashes] Malformed contract (plaintext hash " 57 | "mismatch)"); 58 | 59 | hash = Hash::hash(ctext, ctHash.alg, ctHash.key, ctHash.type); 60 | if (ctHash != hash) 61 | throw CashException(CashException::CE_FE_ERROR, 62 | "[FEContract::checkHashes] Malformed contract (ciphertext hash " 63 | "mismatch)"); 64 | return true; 65 | } 66 | 67 | bool FEContract::checkAHash(const hash_t& ptHash, const hash_t& ctHash) const { 68 | return (checkHash(ptHash, ptHashA) && checkHash(ctHash, ctHashA)); 69 | } 70 | 71 | bool FEContract::checkBHash(const hash_t& ptHash, const hash_t& ctHash) const { 72 | return (checkHash(ptHash, ptHashB) && checkHash(ctHash, ctHashB)); 73 | } 74 | 75 | bool FEContract::checkHash(const hash_t& hashGiven, 76 | const hash_t& hashStored) const { 77 | if (hashGiven != hashStored) 78 | throw CashException(CashException::CE_FE_ERROR, 79 | "[FEContract::checkHash] Malformed contract (hash mismatch)"); 80 | return true; 81 | } 82 | -------------------------------------------------------------------------------- /src/FEMessage.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef _FEMESSAGE_H_ 3 | #define _FEMESSAGE_H_ 4 | 5 | #include "FEContract.h" 6 | 7 | /*! \brief This class is a wrapper for the message sent in Step 4 of the 8 | * barter protocol */ 9 | 10 | class FEMessage { 11 | public: 12 | /*! constructor: takes in escrow (encryption of the symmetric 13 | * key), signature on this escrow, and contract (label for the 14 | * escrow) */ 15 | FEMessage(vector &escrow, string &sig, FEContract &contract) 16 | : escrow(escrow), signature(sig), contract(contract) {} 17 | 18 | FEMessage(string &sig, FEContract &contract) 19 | : signature(sig), contract(contract) {} 20 | 21 | /*! copy constructor */ 22 | FEMessage(const FEMessage &o) 23 | : escrow(o.escrow), signature(o.signature), contract(o.contract) {} 24 | 25 | FEMessage(const string& s) { loadString(*this, s); }; 26 | 27 | // getters 28 | const vector& getEscrow() const { return escrow; } 29 | const string& getSignature() const { return signature; } 30 | const FEContract& getContract() const { return contract; } 31 | 32 | private: 33 | vector escrow; 34 | string signature; 35 | FEContract contract; 36 | 37 | friend class boost::serialization::access; 38 | template 39 | void serialize(Archive& ar, const unsigned int ver) { 40 | ar & auto_nvp(escrow) 41 | & auto_nvp(signature) 42 | & auto_nvp(contract); 43 | } 44 | }; 45 | 46 | #endif /*BARTERMESSAGE_H_*/ 47 | -------------------------------------------------------------------------------- /src/FEResolutionMessage.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef _FERESOLUTIONMESSAGE_H_ 3 | #define _FERESOLUTIONMESSAGE_H_ 4 | 5 | #include "FEMessage.h" 6 | #include "FESetupMessage.h" 7 | 8 | /*! \brief This class is a wrapper around messages sent to the arbiter in 9 | * Stage 1 of the responder's resolution protocol */ 10 | 11 | class FEResolutionMessage { 12 | 13 | public: 14 | FEResolutionMessage(FEMessage* m, FESetupMessage* s, 15 | const vector &k) 16 | : message(m), setupMessage(s), keys(k) {} 17 | 18 | FEResolutionMessage() : message(0), setupMessage(0) {} 19 | 20 | // getters 21 | FEMessage* getMessage() const { return message; } 22 | FESetupMessage* getSetupMessage() const { return setupMessage; } 23 | vector getKeys() const { return keys; } 24 | 25 | private: 26 | FEMessage* message; 27 | FESetupMessage* setupMessage; 28 | vector keys; 29 | 30 | friend class boost::serialization::access; 31 | template 32 | void serialize(Archive& ar, const unsigned int ver) { 33 | ar & auto_nvp(message) 34 | & auto_nvp(setupMessage) 35 | & auto_nvp(keys); 36 | } 37 | }; 38 | 39 | #endif /*_FERESOLUTIONMESSAGE_H_*/ 40 | -------------------------------------------------------------------------------- /src/FESetupMessage.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "FESetupMessage.h" 3 | #include "VEVerifier.h" 4 | 5 | bool FESetupMessage::check(const VEPublicKey* pk, const int stat, 6 | const ZZ& R) const { 7 | // check coin 8 | if (!coinPrime.verifyCoin() || coinPrime.getR() != R) 9 | throw CashException(CashException::CE_FE_ERROR, 10 | "[FESetupMessage::check] Malformed coin"); 11 | 12 | // check verifiable escrow 13 | string label = signPK->publicKeyString(); 14 | VEVerifier verifier(pk); 15 | if (!verifier.verify(*escrow, coinPrime.getEndorsementCom(), 16 | coinPrime.getCashGroup(), label, pk->hashAlg, stat)) 17 | throw CashException(CashException::CE_FE_ERROR, 18 | "[FESetupMessage::check] Malformed escrow"); 19 | 20 | return true; 21 | } 22 | -------------------------------------------------------------------------------- /src/FESetupMessage.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef _FESETUPMESSAGE_H_ 3 | #define _FESETUPMESSAGE_H_ 4 | 5 | #include "Coin.h" 6 | #include "VECiphertext.h" 7 | #include "Signature.h" 8 | #include "VEPublicKey.h" 9 | 10 | /*! \brief This class is a wrapper for the setup message send in Step 1 of the 11 | * barter protocol */ 12 | 13 | class FESetupMessage { 14 | 15 | public: 16 | /*! constructor takes in unendorsed coin, escrow (encryption of 17 | * the endorsement for the coin), and the public key 18 | * for the initiator's signature scheme (label for the 19 | * verifiable escrow) */ 20 | FESetupMessage(const Coin &coinPrime, VECiphertext* escrow, 21 | const Signature::Key &signPK) 22 | : coinPrime(coinPrime), escrow(escrow), signPK(signPK.getPublicKey()) {} 23 | 24 | /*! copy constructor */ 25 | FESetupMessage(const FESetupMessage &o) 26 | : coinPrime(o.coinPrime), escrow(o.escrow), 27 | signPK(new Signature::Key(*o.signPK)) {} 28 | 29 | /*! destructor */ 30 | ~FESetupMessage() { delete signPK; } 31 | 32 | FESetupMessage(const string& s, const BankParameters *params) { 33 | // need to set params for Coin contained in message 34 | loadGZString(make_nvp("FESetupMessage", *this), s); 35 | coinPrime.setParameters(params); 36 | } 37 | 38 | /*! check contents (verify coin and escrow) */ 39 | bool check(const VEPublicKey* pk, const int stat, const ZZ& R) const; 40 | 41 | /*! getters for coin', escrow, and signature PK */ 42 | Coin getCoinPrime() const { return coinPrime; } 43 | VECiphertext* getEscrow() const { return escrow; } 44 | const Signature::Key* getPK() const { return signPK; } 45 | 46 | private: 47 | Coin coinPrime; 48 | VECiphertext* escrow; 49 | Signature::Key* signPK; 50 | 51 | friend class boost::serialization::access; 52 | template 53 | void serialize(Archive& ar, const unsigned int ver) { 54 | ar & auto_nvp(coinPrime) 55 | & auto_nvp(escrow) 56 | & auto_nvp(signPK); 57 | } 58 | 59 | }; 60 | 61 | #endif /*SETUPMESSAGE_H_*/ 62 | -------------------------------------------------------------------------------- /src/FourSquares.h: -------------------------------------------------------------------------------- 1 | #ifndef _FOURSQUARES_H 2 | #define _FOURSQUARES_H 3 | 4 | #include 5 | #include "NTL/ZZ.h" 6 | #include 7 | 8 | NTL_CLIENT 9 | 10 | class FourSquares { 11 | public: 12 | static vector decompose(const ZZ& n); 13 | static vector _decompose(const ZZ& n); 14 | 15 | private: 16 | // Certainty used for finding good primes 17 | static const int primeCertainty = 10; 18 | 19 | // Helper Functions 20 | static bool isProbableSquare(const ZZ& n); 21 | static long jacobi(long b, const ZZ& p); 22 | static vector iunit(const ZZ& p); 23 | static vector isqrtInternal(const ZZ& n, int log2n); 24 | static vector isqrt(const ZZ& n); 25 | static bool isProbablePrime(const ZZ& n, int certainty); 26 | static ZZ nextProbablePrime(const ZZ& n, int certainty); 27 | static vector decomposePrime(const ZZ& p); 28 | static int getLowestSetBit(const ZZ& n); 29 | }; 30 | 31 | #endif /*_FOURSQUARES_H */ 32 | 33 | -------------------------------------------------------------------------------- /src/Group.cpp: -------------------------------------------------------------------------------- 1 | #include "Group.h" 2 | #include "CommonFunctions.h" 3 | #include "CashException.h" 4 | 5 | Group::Group(const string &owner, int modLength, int oLength) 6 | : modulusLength(modLength), orderLength(oLength) 7 | { 8 | isTrusted = CommonFunctions::isTTP(owner); 9 | } 10 | 11 | Group::Group(const Group &o) 12 | : modulusLength(o.modulusLength), orderLength(o.orderLength), 13 | generators(o.generators), isTrusted(o.isTrusted), modulus(o.modulus), 14 | type(o.type) 15 | { 16 | } 17 | 18 | Group::Group(const string &owner, const ZZ &mod) 19 | : modulusLength(NumBits(mod)), orderLength(NumBits(mod)), modulus(mod) 20 | { 21 | isTrusted = CommonFunctions::isTTP(owner); 22 | } 23 | 24 | ZZ Group::randomElement() { 25 | return PowerMod(getGenerator(), randomExponent(), getModulus()); 26 | } 27 | 28 | void Group::debug() const { 29 | cout << "ModulusLength = " << modulusLength << endl; 30 | cout << "OrderLength = " << orderLength << endl; 31 | } 32 | 33 | void Group::makeTrusted() { 34 | if(isTrusted == false) { 35 | if(checkPreconditions()) { 36 | isTrusted = true; 37 | } else { 38 | throw CashException(CashException::CE_UNKNOWN_ERROR, 39 | "[Group::makeTrusted] Precondition checks failed"); 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/GroupPrime.h: -------------------------------------------------------------------------------- 1 | /*! 2 | * \brief This represents a prime-order group, which is a Group. 3 | */ 4 | 5 | #ifndef GROUPPRIME_H_ 6 | #define GROUPPRIME_H_ 7 | 8 | #include "Group.h" 9 | 10 | class GroupPrime : public Group { 11 | public: 12 | /*! Create a new prime-order group with the specified owner, 13 | * a modulus of length modulusLength, a group 14 | * order of length orderLength, and a statistical security 15 | * parameter "stat" */ 16 | GroupPrime(const string &owner, int modulusLength, 17 | int orderLength, int stat); 18 | 19 | /*! Copy constructor -- currently doesn't check pre- or 20 | * post-conditions */ 21 | GroupPrime(const GroupPrime &o) 22 | : Group(o), order(o.order), factor(o.factor), stat(o.stat) {} 23 | 24 | /*! Constructor to load from file */ 25 | GroupPrime(const char *fname) 26 | : Group(), order(0), factor(0), stat(0) 27 | { loadFile(make_nvp("GroupPrime", *this), fname); } 28 | 29 | virtual ZZ getOrder() const { return order; } 30 | virtual ZZ randomExponent() const { return RandomBnd(order); } 31 | long randomnessDomain() const { return orderLength; } 32 | 33 | /*! Adds a new generator to list of generators in group */ 34 | virtual ZZ addNewGenerator(); 35 | 36 | /*! Check if value is an element of our group */ 37 | virtual bool isElement(const ZZ &value) const; 38 | 39 | /*! Check if gen is a generator for this group */ 40 | virtual bool isGenerator(const ZZ &gen) const; 41 | 42 | /*! Check if all generators stored in group actually 43 | * generate group */ 44 | bool checkGroupSetup() const; 45 | 46 | virtual void debug() const; 47 | 48 | protected: 49 | /*! returns true iff 1 <= exp < order */ 50 | bool isProperExponent(const ZZ &exp) const; 51 | 52 | /*! checks to make sure the group satisfies certain properties */ 53 | virtual bool checkPreconditions() const; 54 | 55 | private: 56 | /*! this is for serialization */ 57 | GroupPrime() : Group(), order(0), factor(0), stat(0) {} 58 | 59 | /*! modulus = order*factor + 1 */ 60 | ZZ order; 61 | ZZ factor; 62 | int stat; 63 | 64 | friend class boost::serialization::access; 65 | template 66 | void serialize(Archive& ar, const unsigned int ver) { 67 | ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP(Group); 68 | ar & auto_nvp(order) 69 | & auto_nvp(stat) 70 | & auto_nvp(factor) 71 | ; 72 | } 73 | }; 74 | 75 | #endif /*GROUPPRIME_H_*/ 76 | -------------------------------------------------------------------------------- /src/GroupRSA.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef GROUPRSA_H_ 3 | #define GROUPRSA_H_ 4 | 5 | #include "Group.h" 6 | 7 | /*! \brief This represents a special RSA group (so one where p and q are 8 | * Germain primes). */ 9 | 10 | void setGeneratorCheckMode(int mode); 11 | 12 | class GroupRSA : public Group { 13 | public: 14 | /*! Create a new RSA group with the specified owner name 15 | * "owner", a modulus (n = p * q) of length modulusLength, 16 | * and a statistical safety parameter stat */ 17 | GroupRSA(const string &owner, int modulusLength, 18 | int stat); 19 | 20 | GroupRSA(const string &owner, ZZ &modulus, int s) 21 | : Group(owner, modulus), stat(s) {} 22 | 23 | GroupRSA() : Group(), p(0), q(0), stat(0) {} 24 | 25 | /*! Copy constructor for an RSA group */ 26 | GroupRSA(const GroupRSA &o) 27 | : Group(o), p(o.p), q(o.q), stat(o.stat) {} 28 | 29 | /*! Constructor to load from file */ 30 | GroupRSA(const char *fname) 31 | : Group(), p(0), q(0), stat(0) 32 | { loadFile(make_nvp("GroupRSA", *this), fname); } 33 | 34 | // getters 35 | virtual ZZ getOrder() const; 36 | virtual ZZ getP() const { return p; } 37 | int getStat() const { return stat; } 38 | 39 | /*! Adds a new generator to list of generators in group */ 40 | virtual ZZ addNewGenerator(); 41 | 42 | /*! Select a random exponent -- useful for creating new group 43 | * generators */ 44 | virtual ZZ randomExponent() const 45 | { return RandomLen_ZZ(modulusLength + stat); } 46 | long randomnessDomain() const { return modulusLength + stat; } 47 | 48 | virtual bool isElement(const ZZ &value) const; 49 | virtual bool isGenerator(const ZZ &number) const; 50 | 51 | void clearSecrets() { p = 0; q = 0; } 52 | 53 | /*! debug */ 54 | virtual void debug() const; 55 | 56 | protected: 57 | /*! checks to make sure preconditions are satisfied */ 58 | virtual bool checkPreconditions() const; 59 | 60 | private: 61 | /*! n = p * q; n is known and p,q are private */ 62 | ZZ p, q; 63 | int stat; 64 | 65 | friend class boost::serialization::access; 66 | template 67 | void serialize(Archive& ar, const unsigned int ver) { 68 | ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP(Group); 69 | ar & auto_nvp(p) 70 | & auto_nvp(q) 71 | & auto_nvp(stat) 72 | ; 73 | } 74 | }; 75 | 76 | #endif /*GROUPRSA_H_*/ 77 | -------------------------------------------------------------------------------- /src/GroupSquareMod.cpp: -------------------------------------------------------------------------------- 1 | #include "GroupSquareMod.h" 2 | 3 | GroupSquareMod::GroupSquareMod(const string &owner, ZZ modulus, int st) 4 | : Group(owner, modulus) 5 | { 6 | type = Group::TYPE_SQUARE; 7 | stat = st; 8 | } 9 | 10 | bool GroupSquareMod::isElement(const ZZ &value) const { 11 | if(value < 0) 12 | return false; 13 | if(value >= modulus) 14 | return false; 15 | if(GCD(value, modulus) != 1) 16 | return false; 17 | return true; 18 | } 19 | 20 | bool GroupSquareMod::isGenerator(const ZZ &gen) const { 21 | // check if it's an element of our group 22 | if(!isElement(gen)) 23 | return false; 24 | // check if gen == 1 (mod modulus), ie. the identity => not a generator 25 | if(gen == to_ZZ(1)) 26 | return false; 27 | // we cannot check anything else unfortunately 28 | return true; 29 | } 30 | 31 | void GroupSquareMod::debug() const 32 | { 33 | cout << "GroupSquareMod" << endl; 34 | cout << "Modulus = " << modulus << endl 35 | << "stat = " << stat << endl; 36 | Group::debug(); 37 | } 38 | 39 | -------------------------------------------------------------------------------- /src/GroupSquareMod.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef _GROUPSQUAREMOD_H 3 | #define _GROUPSQUAREMOD_H 4 | 5 | #include "Group.h" 6 | 7 | class GroupSquareMod : public Group { 8 | public: 9 | GroupSquareMod(const string &owner, ZZ modulus, int stat); 10 | 11 | /*! Copy constructor -- currently doesn't check pre- or 12 | * post-conditions */ 13 | GroupSquareMod(const GroupSquareMod &o) : Group(o), stat(o.stat) {} 14 | 15 | // XXX: should we actually fill this in? 16 | virtual ZZ getOrder() const { return ZZ(); } 17 | virtual ZZ addNewGenerator() { return ZZ(); } 18 | 19 | /*! Create a random exponent -- for use when we're trying 20 | * to create new random generators for the group */ 21 | virtual ZZ randomExponent() const 22 | { return RandomLen_ZZ(modulusLength + stat); } 23 | long randomnessDomain() const { return modulusLength + stat; } 24 | 25 | /*! Check if value is an element of our group */ 26 | virtual bool isElement(const ZZ &value) const; 27 | 28 | /*! Check if gen is a generator for this group */ 29 | virtual bool isGenerator(const ZZ &gen) const; 30 | 31 | virtual void debug() const; 32 | 33 | // XXX: fill this in? 34 | /*! Used to determine whether the group is trusted. */ 35 | virtual bool checkPreconditions() const {return true;}; 36 | 37 | private: 38 | int stat; 39 | 40 | friend class boost::serialization::access; 41 | template 42 | void serialize(Archive& ar, const unsigned int ver) { 43 | ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP(Group) 44 | & auto_nvp(stat); 45 | } 46 | }; 47 | 48 | 49 | 50 | #endif /* _GROUPSQUAREMOD_H */ 51 | 52 | -------------------------------------------------------------------------------- /src/Merkle.cpp: -------------------------------------------------------------------------------- 1 | #include "Merkle.h" 2 | 3 | MerkleTree::MerkleTree(const char* buff, int buffSize, 4 | const MerkleContract &contract) 5 | : contract(contract) 6 | { 7 | init(buff, buffSize); 8 | } 9 | 10 | MerkleTree::MerkleTree(const string &str, const MerkleContract &contract) 11 | : contract(contract) 12 | { 13 | init(str.data(), str.size()); 14 | } 15 | 16 | 17 | MerkleTree::MerkleTree(const vector &hashBlocks, 18 | const MerkleContract &contract) 19 | : contract(contract) 20 | { 21 | init(hashBlocks); 22 | } 23 | 24 | vector MerkleTree::initHashChunks(const char* buff, int buffSize){ 25 | unsigned numChunks = buffSize/CHUNK_SIZE; 26 | padStart = numChunks; 27 | 28 | unsigned nextTwoPow = nextPowerOfTwo(numChunks); 29 | height = log_2(nextTwoPow); 30 | 31 | //create a hash_t array of the leaf nodes 32 | vector hashChunks(nextTwoPow); 33 | 34 | for(unsigned i = 0; i MerkleTree::pad(const vector &hashBlocks){ 46 | unsigned numChunks = hashBlocks.size(); 47 | padStart = numChunks; 48 | 49 | unsigned nextTwoPow = nextPowerOfTwo(numChunks); 50 | height = log_2(nextTwoPow); 51 | 52 | //create a hash_t array of the leaf nodes 53 | vector hashChunks(nextTwoPow); 54 | 55 | for(unsigned i = 0; i &chunks){ 68 | //a binary tree has 2 * numLeaves -1 nodes 69 | unsigned treeSize = 2*getNumLeaves()-1; 70 | //create an array to hold the binary tree 71 | vector m_tree(treeSize); 72 | //initialize the leaves to chunks 73 | int x; 74 | int y; 75 | for(x = treeSize -1, y = getNumLeaves()-1; y>=0; x--, y--){ 76 | m_tree[x]=chunks[y]; 77 | } 78 | //compute the rest of the hash tree 79 | for(int x = treeSize-1-getNumLeaves(); x>=0; x--){ 80 | m_tree[x] = contract.hash(m_tree[2*x+1], m_tree[2*x+2]); 81 | } 82 | //return the root 83 | return m_tree[0]; 84 | } 85 | 86 | void MerkleTree::init(const char* buff, int buffSize){ 87 | leaves = initHashChunks(buff, buffSize); 88 | root = makeRoot(leaves); 89 | root.type=Hash::TYPE_MERKLE; 90 | } 91 | 92 | void MerkleTree::init(const vector &hashBlocks){ 93 | leaves = pad(hashBlocks); 94 | root = makeRoot(leaves); 95 | root.type=Hash::TYPE_MERKLE; 96 | } 97 | 98 | 99 | -------------------------------------------------------------------------------- /src/Merkle.h: -------------------------------------------------------------------------------- 1 | #ifndef _MERKLE_H_ 2 | #define _MERKLE_H_ 3 | 4 | #include "MerkleContract.h" 5 | 6 | //constructs a binary representation 7 | inline pathbits binaryRepresentation(int x){ 8 | pathbits ret(x); 9 | return ret; 10 | } 11 | 12 | //needed for bit flipping 13 | inline unsigned binToInt(pathbits bin){ 14 | return bin.to_ulong(); 15 | } 16 | 17 | inline bool powerOfTwo(int x){ 18 | return !(x & (x - 1)) && x; 19 | } 20 | 21 | // from http://www-graphics.stanford.edu/~seander/bithacks.html 22 | inline unsigned log_2(int x){ 23 | union { unsigned int u[2]; double d; } t; // temp 24 | t.u[BYTE_ORDER==LITTLE_ENDIAN] = 0x43300000; 25 | t.u[BYTE_ORDER!=LITTLE_ENDIAN] = x; 26 | t.d -= 4503599627370496.0; 27 | return (t.u[BYTE_ORDER==LITTLE_ENDIAN] >> 20) - 0x3FF; 28 | } 29 | 30 | inline unsigned nextPowerOfTwo(int x){ 31 | if(powerOfTwo(x)){ 32 | return x; 33 | } else{ 34 | return 1<<(log_2(x)+1); 35 | } 36 | } 37 | 38 | class MerkleTree { 39 | 40 | public: 41 | MerkleTree(const char* buff, int buffSize, 42 | const MerkleContract &contract); 43 | MerkleTree(const string& str, const MerkleContract &contract); 44 | MerkleTree(const vector &hashBlocks, 45 | const MerkleContract &contract); 46 | 47 | unsigned getHeight() const {return height;} 48 | vector getLeaves() const {return leaves;} 49 | hash_t getRoot() const {return root;} 50 | unsigned getNumLeaves() const {return 1 << height;} 51 | 52 | private: 53 | vector initHashChunks(const char* buff, int buffSize); 54 | hash_t makeRoot(const vector &chunks); 55 | void init(const char* buff, int buffSize); 56 | void init(const vector &hashBlocks); 57 | vector pad(const vector &hashBlocks); 58 | 59 | MerkleContract contract; 60 | hash_t root; 61 | vector leaves; 62 | unsigned padStart; 63 | unsigned height; 64 | }; 65 | 66 | #endif 67 | -------------------------------------------------------------------------------- /src/MerkleContract.h: -------------------------------------------------------------------------------- 1 | #ifndef _MERKLECONTRACT_H_ 2 | #define _MERKLECONTRACT_H_ 3 | 4 | #include 5 | #include "Ciphertext.h" 6 | #define CHUNK_SIZE 1024 7 | 8 | typedef bitset<32> pathbits; 9 | 10 | struct hashDirect{ 11 | hash_t node; 12 | pathbits path; 13 | }; 14 | 15 | typedef vector > hash_matrix; 16 | 17 | class MerkleContract { 18 | public: 19 | MerkleContract(){} 20 | MerkleContract(const string key, hashalg_t alg): key(key), alg(alg) {} 21 | MerkleContract(const MerkleContract &o) : key(o.key), alg(o.alg) {} 22 | 23 | hash_t hash(hash_t left, hash_t right) const { 24 | return Hash::hash(left.str() + right.str(), alg, key, 25 | Hash::TYPE_PLAIN); 26 | } 27 | 28 | hash_t hash(const char * buff, int buffSize) const { 29 | return Hash::hash(buff, buffSize, alg, key, Hash::TYPE_PLAIN); 30 | } 31 | 32 | template 33 | hash_t hash(T* buff) const { 34 | return hash(buff->data(), buff->size()); 35 | } 36 | 37 | hash_t hash(const string& str) const { 38 | return hash(str.data(), str.size()); 39 | } 40 | 41 | private: 42 | string key; 43 | hashalg_t alg; 44 | 45 | friend class boost::serialization::access; 46 | template 47 | void serialize(Archive& ar, const unsigned int ver) { 48 | ar & auto_nvp(key) 49 | & auto_nvp(alg); 50 | } 51 | }; 52 | 53 | #endif 54 | -------------------------------------------------------------------------------- /src/MerkleProof.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "MerkleProof.h" 3 | 4 | MerkleProof::MerkleProof(const vector &ctextBlocks, 5 | const hash_matrix &ctextProof, 6 | const hash_matrix &fileProof, 7 | MerkleContract* ctContract, 8 | MerkleContract* ptContract) 9 | : ctextBlocks(ctextBlocks), ctextProof(ctextProof), fileProof(fileProof), 10 | ctContract(ctContract), ptContract(ptContract) 11 | { 12 | plaintext = ""; 13 | empty=false; 14 | } 15 | 16 | MerkleProof::MerkleProof(const vector &ctextBlocks, 17 | const hash_matrix &ctextProof, 18 | const string &plaintext, MerkleContract* ctContract) 19 | : ctextBlocks(ctextBlocks), ctextProof(ctextProof), plaintext(plaintext), 20 | ctContract(ctContract) {empty=false;} 21 | 22 | MerkleProof::MerkleProof(const vector &ctextBlocks, 23 | const hash_matrix &ctextProof, 24 | MerkleContract* ctContract) 25 | : ctextBlocks(ctextBlocks), ctextProof(ctextProof), ctContract(ctContract) 26 | { 27 | } 28 | 29 | MerkleProof::MerkleProof(const MerkleProof &o) 30 | : ctextBlocks(o.ctextBlocks), ctextProof(o.ctextProof), 31 | fileProof(o.fileProof), plaintext(o.plaintext), ctContract(o.ctContract), 32 | ptContract(o.ptContract), empty(o.empty) 33 | { 34 | } 35 | -------------------------------------------------------------------------------- /src/MerkleProof.h: -------------------------------------------------------------------------------- 1 | #ifndef MERKLEPROOF_H_ 2 | #define MERKLEPROOF_H_ 3 | 4 | #include "MerkleContract.h" 5 | 6 | /*! \brief This class is just a storage container for the two Merkle 7 | * proofs we need for fair exchange resolutions */ 8 | 9 | class MerkleProof { 10 | public: 11 | MerkleProof() : ctContract(0), ptContract(0) {empty=true;} 12 | 13 | /*! ctextBlocks represent the blocks of the ciphertext that we are 14 | * proving are correct; ctextProof is the proof that the Merkle hash 15 | * of the ciphertext was formed correctly; fileProof is the proof 16 | * that the Merkle hash of the plaintext was formed correctly 17 | * the contracts store the hashalg and key */ 18 | MerkleProof(const vector &ctextBlocks, 19 | const hash_matrix &ctextProof, 20 | const hash_matrix &fileProof, 21 | MerkleContract* ctContract, MerkleContract* ptContract); 22 | 23 | MerkleProof(const vector &ctextBlocks, 24 | const hash_matrix &ctextProof, const string &plaintext, 25 | MerkleContract* ctContract); 26 | 27 | MerkleProof(const vector &ctextBlocks, 28 | const hash_matrix &ctextProof, MerkleContract* ctContract); 29 | 30 | MerkleProof(const MerkleProof &o); 31 | 32 | // getters 33 | vector getCTextBlocks() const { return ctextBlocks; } 34 | hash_matrix getCTextProof() const { return ctextProof; } 35 | hash_matrix getPTextProof() const { return fileProof; } 36 | string getPlaintext() const { return plaintext; } 37 | MerkleContract* getPTContract() const { return ptContract; } 38 | MerkleContract* getCTContract() const { return ctContract; } 39 | bool isEmpty() const { return empty; } 40 | 41 | private: 42 | vector ctextBlocks; 43 | hash_matrix ctextProof; 44 | hash_matrix fileProof; 45 | string plaintext; 46 | MerkleContract* ctContract; 47 | MerkleContract* ptContract; 48 | bool empty; 49 | 50 | friend class boost::serialization::access; 51 | template 52 | void serialize(Archive& ar, const unsigned int ver) { 53 | ar & auto_nvp(ctextBlocks) 54 | & auto_nvp(ctextProof) 55 | & auto_nvp(fileProof) 56 | & auto_nvp(plaintext) 57 | & auto_nvp(ctContract) 58 | & auto_nvp(ptContract) 59 | & auto_nvp(empty); 60 | } 61 | }; 62 | 63 | #endif /*MERKLEPROOF_H_*/ 64 | -------------------------------------------------------------------------------- /src/MerkleProver.cpp: -------------------------------------------------------------------------------- 1 | #include "MerkleProver.h" 2 | 3 | MerkleProver::MerkleProver(const vector &hashBlocks, 4 | const MerkleContract &contract) 5 | : contract(contract) 6 | { 7 | tree = new MerkleTree(hashBlocks, contract); 8 | } 9 | 10 | MerkleProver::MerkleProver(const char* buff, int buffSize, 11 | const MerkleContract& contract) 12 | : contract(contract), tree(0) 13 | { 14 | init(buff, buffSize); 15 | } 16 | 17 | 18 | MerkleProver::MerkleProver(const string &str, const MerkleContract &contract) 19 | : contract(contract) 20 | { 21 | init(str.data(), str.size()); 22 | } 23 | 24 | MerkleProver::MerkleProver(const vector &encBuffs, 25 | const MerkleContract &contract) 26 | : contract(contract) 27 | { 28 | vector hashBlocks(encBuffs.size()); 29 | for(unsigned x=0; x& buffs, 36 | const MerkleContract &contract) 37 | : contract(contract) 38 | { 39 | vector hashBlocks(buffs.size()); 40 | for(unsigned x=0; x &challenges){ 46 | hash_matrix toReturn; 47 | unsigned treeSize = 2*getNumBlocks()-1; 48 | vector m_tree(treeSize); 49 | //initialize the leaves to chunks 50 | vector leaves = tree->getLeaves(); 51 | int x; 52 | int y; 53 | for(x = treeSize -1, y = getNumBlocks()-1; y>=0; x--, y--){ 54 | m_tree[x]=leaves[y]; 55 | } 56 | 57 | for(unsigned x = 0; x MerkleProver::generateProof(unsigned challenge, 64 | vector &m_tree){ 65 | vector toReturn; 66 | 67 | //construct a binary represention of the chunk index 68 | pathbits path = binaryRepresentation(challenge); 69 | 70 | //push back the chunk itself 71 | hashDirect chunk; 72 | chunk.node=m_tree[getNumBlocks() - 1 + challenge]; 73 | chunk.path = path; 74 | toReturn.push_back(chunk); 75 | 76 | //should get all the neighbors 77 | for(unsigned height = tree->getHeight(); height>=1; height--){ 78 | hashDirect temp; 79 | path.flip(0); 80 | unsigned index = (1<>= 1; 86 | } 87 | return toReturn; 88 | } 89 | 90 | hash_t MerkleProver::computeSubTree(unsigned index, vector &m_tree){ 91 | if(m_tree[index].empty()){ 92 | m_tree[index] = contract.hash(computeSubTree(index*2 +1, m_tree), 93 | computeSubTree(index*2+2, m_tree)); 94 | } 95 | return m_tree[index]; 96 | } 97 | 98 | 99 | void MerkleProver::init(const char* buff, int buffSize){ 100 | tree = new MerkleTree(buff, buffSize, contract); 101 | } 102 | 103 | 104 | 105 | -------------------------------------------------------------------------------- /src/MerkleProver.h: -------------------------------------------------------------------------------- 1 | #ifndef _MERKLEPROVER_H_ 2 | #define _MERKLEPROVER_H_ 3 | 4 | #include "Merkle.h" 5 | 6 | class MerkleProver { 7 | 8 | public: 9 | MerkleProver(const vector &encBuffs, 10 | const MerkleContract &contract); 11 | 12 | MerkleProver(const vector &buffs, 13 | const MerkleContract &contract); 14 | 15 | MerkleProver(const string &str, const MerkleContract &contract); 16 | 17 | MerkleProver(const char* buff, int buffSize, 18 | const MerkleContract &contract); 19 | 20 | MerkleProver(const vector &hashBlocks, 21 | const MerkleContract &contract); 22 | 23 | hash_matrix generateProofs(const vector &challenges); 24 | 25 | unsigned getNumBlocks() const { return tree->getNumLeaves(); } 26 | hash_t getRoot() const { return tree->getRoot(); } 27 | 28 | private: 29 | vector generateProof(unsigned challenge, 30 | vector &m_tree); 31 | 32 | void init(const char* buff, int buffSize); 33 | 34 | hash_t computeSubTree(unsigned index, vector &m_tree); 35 | 36 | MerkleContract contract; 37 | MerkleTree* tree; 38 | 39 | }; 40 | 41 | #endif 42 | -------------------------------------------------------------------------------- /src/MerkleVerifier.cpp: -------------------------------------------------------------------------------- 1 | #include "MerkleVerifier.h" 2 | #include 3 | #define numChallenges 22 4 | #define MIN(x, y) ( (x) < (y) ? (x) : (y) ) 5 | 6 | MerkleVerifier::MerkleVerifier(const hash_t &rt, unsigned numLeaves, 7 | const MerkleContract &contract) 8 | : contract(contract) 9 | { 10 | numBlocks = numLeaves; 11 | root = rt; 12 | challenges = generateChallenges(); 13 | } 14 | 15 | vector MerkleVerifier::generateChallenges() { 16 | unsigned nChallenges = MIN(numBlocks, numChallenges); 17 | vector toReturn; 18 | while(toReturn.size() < nChallenges) { 19 | unsigned rand = NTL::RandomBnd(numBlocks); 20 | vector::iterator it = std::find(toReturn.begin(), 21 | toReturn.end(), rand); 22 | if (it != toReturn.end()) 23 | continue; 24 | toReturn.push_back(NTL::RandomBnd(numBlocks)); 25 | } 26 | return toReturn; 27 | } 28 | 29 | bool MerkleVerifier::verifyProofs(const hash_matrix &proofs){ 30 | bool valid = true; 31 | unsigned i = 0; 32 | do { 33 | vector ith = proofs[i]; 34 | valid = checkProof(ith); 35 | i++; 36 | } while(valid && i < proofs.size()); 37 | return valid; 38 | } 39 | 40 | bool MerkleVerifier::checkProof(vector &proof) { 41 | if(proof.size() == 1){ 42 | proof[0].node.type = Hash::TYPE_MERKLE; 43 | return (proof[0].node == root); 44 | } 45 | for(unsigned i = 0; i < proof.size()-1; i++) { 46 | if(proof[i+1].path[0]){ 47 | proof[i+1].node = contract.hash(proof[i].node, proof[i+1].node); 48 | } else { 49 | proof[i+1].node = contract.hash(proof[i+1].node, proof[i].node); 50 | } 51 | } 52 | proof[proof.size()-1].node.type = Hash::TYPE_MERKLE; 53 | return (proof[proof.size()-1].node == root); 54 | } 55 | 56 | -------------------------------------------------------------------------------- /src/MerkleVerifier.h: -------------------------------------------------------------------------------- 1 | #ifndef _MERKLEVERIFIER_H_ 2 | #define _MERKLEVERIFIER_H_ 3 | 4 | #include "MerkleContract.h" 5 | 6 | class MerkleVerifier { 7 | 8 | public: 9 | MerkleVerifier(const hash_t &rt, unsigned numLeaves, 10 | const MerkleContract &contract); 11 | 12 | vector getChallenges() const { return challenges; } 13 | 14 | /*! checks to see if each proof is valid (using checkProof) */ 15 | bool verifyProofs(const hash_matrix &proofs); 16 | 17 | private: 18 | /*! generates pseudorandom challenges of the appropriate size */ 19 | vector generateChallenges(); 20 | 21 | /*! checks an individual proof to see if it is valid */ 22 | bool checkProof(vector &proof); 23 | 24 | MerkleContract contract; 25 | hash_t root; 26 | unsigned numBlocks; 27 | vector challenges; 28 | }; 29 | 30 | #endif 31 | -------------------------------------------------------------------------------- /src/MultiExp.h: -------------------------------------------------------------------------------- 1 | #ifndef MULTIEXP_H_ 2 | #define MULTIEXP_H_ 3 | 4 | #include 5 | #include 6 | 7 | NTL_CLIENT 8 | /* 9 | * --Multi Exponentiation: Whenever there is more than one base that will be 10 | * raised to more than one exponent, this must be used for efficiency. 11 | */ 12 | 13 | // Multi Exponentiation 14 | // set cacheBases to false if these bases will not be used again 15 | 16 | #ifndef PROFILE_MULTIEXP 17 | 18 | ZZ MultiExp(const vector &bases, const vector &exponents, 19 | const ZZ &modulus, bool cacheBases=true); 20 | #define MultiExpOnce(b,e,m) MultiExp((b),(e),(m),false) 21 | #else 22 | // profiling: record FILE/LINE number of each caller 23 | ZZ MultiExp_(const vector &bases, const vector &exponents, 24 | const ZZ &modulus, bool cacheBases, const char* fn, unsigned line); 25 | #define MultiExp(b,e,m) MultiExp_((b),(e),(m),true,__FILE__,__LINE__) 26 | #define MultiExpOnce(b,e,m) MultiExp_((b),(e),(m),false,__FILE__,__LINE__) 27 | #endif 28 | 29 | #endif 30 | -------------------------------------------------------------------------------- /src/NTL/tools.h: -------------------------------------------------------------------------------- 1 | #include "ZZ.h" 2 | -------------------------------------------------------------------------------- /src/NTL/vec_ZZ.h: -------------------------------------------------------------------------------- 1 | #ifndef __GMPXX_VEC_ZZ_H__ 2 | #define __GMPXX_VEC_ZZ_H__ 3 | #include 4 | #include 5 | #include 6 | 7 | namespace NTL { 8 | // from NTL/tools.h 9 | #ifndef NTL_tools__H 10 | struct INIT_SIZE_STRUCT { }; 11 | const INIT_SIZE_STRUCT INIT_SIZE = INIT_SIZE_STRUCT(); 12 | typedef const INIT_SIZE_STRUCT& INIT_SIZE_TYPE; 13 | #endif 14 | 15 | // a vec_ZZ just subclasses vector to define length() and SetLength() 16 | typedef std::vector vec_ZZ_t; 17 | class vec_ZZ : public vec_ZZ_t { 18 | public: 19 | vec_ZZ() : vec_ZZ_t() {} 20 | vec_ZZ(INIT_SIZE_TYPE i, long n) : vec_ZZ_t(n) {} 21 | vec_ZZ(const vec_ZZ_t& v) : vec_ZZ_t(v) {} 22 | long length() const { return size(); } 23 | void SetLength(long n) { resize(n); } 24 | // convert vector to vec_ZZ subclass 25 | vec_ZZ& operator=(const vec_ZZ_t& other) { 26 | vec_ZZ_t::operator=(other); 27 | return *this; 28 | } 29 | friend class boost::serialization::access; 30 | template 31 | void serialize(Archive& ar, const unsigned int ver) { 32 | ar & boost::serialization::base_object(*this); 33 | } 34 | }; 35 | 36 | // NTL's vec_ZZ.clear() leaves length unchanged 37 | inline void clear(vec_ZZ &v) { size_t l = v.size(); v.clear(); v.resize(l); } 38 | 39 | inline void append(vec_ZZ& v, const ZZ& z) { v.push_back(z); } 40 | inline void append(vec_ZZ& v, const vec_ZZ& z) { 41 | std::copy(z.begin(), z.end(), std::back_inserter(v)); 42 | } 43 | 44 | inline std::ostream& operator<<(std::ostream& s, const vec_ZZ &v) { 45 | bool once = true; 46 | s << "["; 47 | for (vec_ZZ::const_iterator i = v.begin(); i != v.end(); ++i) { 48 | if (once) { once = false; } 49 | else { s << " "; } 50 | s << *i << " "; 51 | } 52 | s << "]"; 53 | return s; 54 | } 55 | 56 | // result must have length n 57 | inline vec_ZZ VectorCopy(const vec_ZZ& a, long n) { 58 | vec_ZZ ret(INIT_SIZE, n); // all set to 0 59 | for (unsigned i = 0; i < a.size(); i++) 60 | ret[i] = a[i]; 61 | return ret; 62 | } 63 | }; 64 | #endif 65 | -------------------------------------------------------------------------------- /src/ProgramMaker.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef _PROGRAMMAKER_H_ 3 | #define _PROGRAMMAKER_H_ 4 | 5 | #include "ZKP/DLRepresentation.h" 6 | #include "Group.h" 7 | 8 | // the following are useful for CLBlindRecipient and CLSignatureProver 9 | // for groups, need access to group object and names of generators 10 | typedef pair > group_pair; 11 | typedef boost::unordered_map gen_group_map; 12 | 13 | // for commitments, we'll assume that value being committed to is called 14 | // x and randomness used is called r; also assume commitment name is 15 | // just c 16 | struct CommitmentInfo { 17 | CommitmentInfo(const ZZ &val, const vector &bNames, 18 | const string &grp) 19 | : comValue(val), baseNames(bNames), group(grp) {} 20 | 21 | ZZ comValue; 22 | vector baseNames; 23 | string group; 24 | }; 25 | 26 | // this is useful for pairing a value with the randomness used to form 27 | // its corresponding commitment 28 | typedef pair SecretValue; 29 | 30 | class ProgramMaker { 31 | 32 | public: 33 | ProgramMaker() {} 34 | 35 | /*! given the various group and commitment names, creates a CL 36 | * program for obtaining a signature */ 37 | static string makeCLObtain(const string &grpPart, 38 | const string &comPart, 39 | const string &comRelPart); 40 | 41 | static string makeCLObtain(const gen_group_map &grps, 42 | const vector &coms); 43 | 44 | static string makeCLProve(const string &grpPart, const string &comPart, 45 | const string &comRelPart); 46 | 47 | static string makeCLProve(const gen_group_map &grps, 48 | const vector &coms); 49 | 50 | static string makeGeneratorList(const vector &genNames); 51 | 52 | static string makeCommitmentForm(const string &cName, 53 | const vector &bNames, 54 | const vector &eNames); 55 | 56 | static string nameGroups(const gen_group_map &grps); 57 | 58 | static pair nameComs(const vector &c); 59 | 60 | }; 61 | 62 | #endif /*_PROGRAMMAKER_H_*/ 63 | -------------------------------------------------------------------------------- /src/SigmaProof.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "SigmaProof.h" 3 | 4 | SigmaProof::SigmaProof(const SigmaProof &o) 5 | : randomizedProofs(o.randomizedProofs), responses(o.responses), 6 | hashAlg(o.hashAlg), commitments(o.commitments) 7 | { 8 | } 9 | 10 | ZZ SigmaProof::computeChallenge() const { 11 | ZZ result; 12 | vector randProofValues; 13 | for (var_map::const_iterator it = randomizedProofs.begin(); 14 | it != randomizedProofs.end(); ++it) { 15 | randProofValues.push_back(it->second); 16 | } 17 | result = Hash::hash(randProofValues, hashAlg); 18 | return result; 19 | } 20 | 21 | void SigmaProof::dump() const { 22 | cout << "SigmaProof (hashAlg " << hashAlg << ")" << endl; 23 | for (var_map::const_iterator it = randomizedProofs.begin(); 24 | it != randomizedProofs.end(); ++it) 25 | cout << "rproofs " << it->first << " : " << it->second << endl; 26 | for (var_map::const_iterator it = responses.begin(); 27 | it != responses.end(); ++it) 28 | cout << "responses " << it->first << " : " << it->second << endl; 29 | for (var_map::const_iterator it = commitments.begin(); 30 | it != commitments.end(); ++it) 31 | cout << "commitments " << it->first << " : " << it->second << endl; 32 | } 33 | -------------------------------------------------------------------------------- /src/SigmaProof.h: -------------------------------------------------------------------------------- 1 | /** 2 | * A generic sigma proof. A sigma proof roughly corresponds to the prover's 3 | * end of a non-interactive zero-knowledge proof. In practice, it acts a lot 4 | * like a SigmaProver. 5 | * 6 | * A sigma proof holds 3 messages: 7 | * - Round 1 messages, which we call randomized proofs 8 | * - Round 2 messages, which we call challenges 9 | * - Round 3 messages, which we call responses 10 | */ 11 | 12 | #ifndef SIGMAPROOF_H_ 13 | #define SIGMAPROOF_H_ 14 | 15 | #include "CommonFunctions.h" 16 | #include "Debug.h" 17 | #include "Hash.h" 18 | 19 | #ifdef USE_STD_MAP 20 | #include 21 | typedef map var_map; 22 | #else 23 | #include 24 | typedef boost::unordered_map var_map; 25 | #endif 26 | 27 | class SigmaProof { 28 | public: 29 | /*! constructs a 3-round sigma proof */ 30 | SigmaProof(const var_map &rproofs, const var_map &coms, 31 | const hashalg_t &ha) 32 | : randomizedProofs(rproofs), hashAlg(ha), commitments(coms) {} 33 | 34 | /*! copy constructor */ 35 | SigmaProof(const SigmaProof &o); 36 | 37 | /*! dummy constructor for initializing empty class members */ 38 | SigmaProof() {} 39 | 40 | /*! computes the challenge (second message) of the proof */ 41 | ZZ computeChallenge() const; 42 | 43 | /*! sets our responses */ 44 | void setResponse(var_map &rs) { responses = rs; } 45 | 46 | var_map getCommitments() const { return commitments; } 47 | 48 | /*! gets a vector of possible first-round messages */ 49 | var_map getRandomizedProofs() const { return randomizedProofs; } 50 | 51 | /*! gets our third-round messages */ 52 | var_map getResponses() const { return responses; } 53 | 54 | // XXX: what about commitments? 55 | bool operator==(const SigmaProof& other) { 56 | return (randomizedProofs == other.randomizedProofs && 57 | responses == other.responses && 58 | hashAlg == other.hashAlg); 59 | } 60 | 61 | void dump() const; 62 | 63 | var_map randomizedProofs; 64 | var_map responses; 65 | hashalg_t hashAlg; 66 | var_map commitments; 67 | 68 | friend class boost::serialization::access; 69 | template 70 | void serialize(Archive& ar, const unsigned int ver) { 71 | ar & auto_nvp(randomizedProofs) 72 | & auto_nvp(responses) 73 | & auto_nvp(hashAlg) 74 | & auto_nvp(commitments); 75 | } 76 | }; 77 | 78 | #endif /*SIGMAPROOF_H_*/ 79 | -------------------------------------------------------------------------------- /src/SigmaProver.cpp: -------------------------------------------------------------------------------- 1 | #include "SigmaProver.h" 2 | 3 | SigmaProof SigmaProver::getSigmaProof(const hashalg_t &hashAlg) { 4 | SigmaProof result(randomizedProofs(), getCommitments(), hashAlg); 5 | var_map hm = respond(result.computeChallenge()); 6 | result.setResponse(hm); 7 | 8 | return result; 9 | } 10 | -------------------------------------------------------------------------------- /src/SigmaProver.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef SIGMAPROVER_H_ 3 | #define SIGMAPROVER_H_ 4 | 5 | #include "SigmaProof.h" 6 | #include "Group.h" 7 | 8 | class SigmaProver { 9 | public: 10 | SigmaProver(){} 11 | SigmaProver(const SigmaProver &original){} 12 | 13 | virtual ~SigmaProver(){} 14 | 15 | virtual var_map getCommitments() = 0; 16 | virtual var_map randomizedProofs() = 0; 17 | 18 | /*! computes and returns response(s) according to challenge */ 19 | virtual var_map respond(const ZZ &challenge) = 0; 20 | 21 | /*! calls randomizedProof and respond methods */ 22 | SigmaProof getSigmaProof(const hashalg_t &hashAlg); 23 | }; 24 | 25 | #endif /* SIGMAPROVER_H_ */ 26 | -------------------------------------------------------------------------------- /src/SigmaVerifier.cpp: -------------------------------------------------------------------------------- 1 | #include "SigmaVerifier.h" 2 | 3 | ZZ SigmaVerifier::getNewChallenge() { 4 | 5 | // don't perform this check for now 6 | /*if(!canGenerateNewChallenge()) 7 | { 8 | throw CashException(CashException::CE_UNKNOWN_ERROR, 9 | "[SigmaVerifier::getNewChallenge] Not allowed to generate a " 10 | "challenge at this point in the algorithm"); 11 | } 12 | */ 13 | return generateChallenge(); 14 | } 15 | 16 | ZZ SigmaVerifier::generateChallenge() { 17 | ZZ chal = RandomLen_ZZ(2 * stat); 18 | setChallenge(chal); 19 | return chal; 20 | } 21 | -------------------------------------------------------------------------------- /src/SigmaVerifier.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Verifier class for a sigma proof. This is a parent class for specific proofs. 3 | */ 4 | 5 | #ifndef SIGMAVERIFIER_H_ 6 | #define SIGMAVERIFIER_H_ 7 | 8 | #include "SigmaProof.h" 9 | #include "Group.h" 10 | 11 | class SigmaVerifier { 12 | public: 13 | /*! randomized Proof will only be set via constructor */ 14 | SigmaVerifier(const var_map &rp, int st) : rProof(rp), stat(st) {} 15 | 16 | /*! copy constructor */ 17 | SigmaVerifier(const SigmaVerifier &o) 18 | : challenge(o.challenge), rProof(o.rProof), stat(o.stat) {} 19 | 20 | /*! destructor */ 21 | virtual ~SigmaVerifier() {} 22 | 23 | /*! will return a new challenge if canGenerateNewChallenge 24 | * is true */ 25 | ZZ getChallenge() const { return challenge; } 26 | 27 | virtual void setChallenge(const ZZ &challengeArg) = 0; 28 | ZZ getNewChallenge(); 29 | 30 | virtual bool canGenerateNewChallenge() const = 0; 31 | 32 | /*! the response of SigmaProof will not be stored 33 | * but used in the computation of the verification equation */ 34 | virtual bool verify(var_map &response) = 0; 35 | 36 | /*! will get first-round message of the sigma proof */ 37 | var_map getRandomizedProofs() const { return rProof; } 38 | 39 | protected: 40 | /*! to be used by getChallenge if canGenerateNewChallenge 41 | * returns true */ 42 | ZZ generateChallenge(); 43 | ZZ challenge; 44 | 45 | private: 46 | var_map rProof; 47 | int stat; 48 | }; 49 | 50 | 51 | #endif /* SIGMAVERIFIER_H_ */ 52 | -------------------------------------------------------------------------------- /src/Timer.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Timer.cpp 3 | * 4 | * Created on: Feb 8, 2009 5 | * Author: kupcu 6 | */ 7 | #include "Timer.h" 8 | 9 | #ifdef TIMER 10 | #include "CashException.h" 11 | #include 12 | #include 13 | 14 | vector brownieTimerValue; 15 | void startTimer() { 16 | timeval t; 17 | gettimeofday(&t, NULL); 18 | brownieTimerValue.push_back(t); 19 | } 20 | 21 | /* Determine the difference, in milliseconds, between two struct timevals. */ 22 | #define TV_DIFF_MS(a, b) \ 23 | (((b).tv_sec - (a).tv_sec) * 1000 + ((b).tv_usec - (a).tv_usec) / 1000) 24 | /* Determine the difference, in microseconds, between two struct timevals. */ 25 | #define TV_DIFF_US(a, b) \ 26 | (((b).tv_sec - (a).tv_sec) * 1000000 + ((b).tv_usec - (a).tv_usec)) 27 | 28 | double printTimer(const string &msg) { 29 | long long elapsed = elapsedTime(); 30 | cout << msg << " [" << elapsed/1000.0 << " ms]" << endl; 31 | return elapsed/1000.0; 32 | } 33 | 34 | double printTimer(const int index, const string &msg) { 35 | long long elapsed = elapsedTime(); 36 | cout << index << ":" << msg << " [" << elapsed/1000.0 << " ms]" << endl; 37 | return elapsed/1000.0; 38 | } 39 | 40 | long long elapsedTime() { 41 | timeval now; 42 | gettimeofday(&now, NULL); 43 | if (brownieTimerValue.size() == 0) 44 | throw CashException(CashException::CE_TIMER_ERROR, 45 | "[Timer::printTimer] No running timer found. " 46 | "Maybe you forgot to start one?"); 47 | long long elapsed = TV_DIFF_US(brownieTimerValue.back(), now); 48 | brownieTimerValue.pop_back(); 49 | return elapsed; 50 | } 51 | 52 | #endif 53 | -------------------------------------------------------------------------------- /src/Timer.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Timer.h 3 | * 4 | * Created on: Feb 8, 2009 5 | * Author: kupcu 6 | */ 7 | 8 | #include "Debug.h" 9 | 10 | #include 11 | #include 12 | 13 | #ifndef TIMER_H_ 14 | #define TIMER_H_ 15 | 16 | #ifdef TIMER 17 | void startTimer(); 18 | double printTimer(const string &msg); 19 | double printTimer(const int index, const string &msg); 20 | long long elapsedTime(); 21 | #else 22 | inline void startTimer() {} 23 | inline double printTimer(const string &msg) { return 0; } 24 | inline double printTimer(const int index, const string &msg) { return 0; } 25 | inline long long elapsedTime() { return 0; } 26 | #endif 27 | 28 | #endif /* TIMER_H_ */ 29 | -------------------------------------------------------------------------------- /src/UserTool.cpp: -------------------------------------------------------------------------------- 1 | #include "UserTool.h" 2 | 3 | UserTool::UserTool(int st, int l, const BankParameters *bp, 4 | const VEPublicKey &vPK, const VEPublicKey &rPK, 5 | const hashalg_t &ha) 6 | : stat(st), lx(l), bankParameters(new BankParameters(*bp)), 7 | vepk(vPK), pk(rPK), hashAlg(ha) 8 | { 9 | const GroupPrime* cashGroup = bankParameters->getCashGroup(); 10 | userSecretKey = cashGroup->randomExponent(); 11 | 12 | // now compute user public key = g^sk_u 13 | ZZ g = cashGroup->getGenerator(1); 14 | userPublicKey = PowerMod(g, userSecretKey, cashGroup->getModulus()); 15 | // also compute PoK of sk_u (useful later) 16 | // set up environment 17 | group_map groups; 18 | groups["G"] = cashGroup; 19 | variable_map v; 20 | v["pk_u"] = userPublicKey; 21 | v["sk_u"] = userSecretKey; 22 | // now compute proof and save it 23 | InterpreterProver p; 24 | p.check(CommonFunctions::getZKPDir()+"/userid.txt", groups); 25 | p.compute(v); 26 | idProof = p.computeProof(hashAlg); 27 | } 28 | -------------------------------------------------------------------------------- /src/UserTool.h: -------------------------------------------------------------------------------- 1 | #ifndef _USERTOOL_H_ 2 | #define _USERTOOL_H_ 3 | 4 | #include "UserWithdrawTool.h" 5 | #include "Buyer.h" 6 | #include "Seller.h" 7 | #include "FEInitiator.h" 8 | #include "FEResponder.h" 9 | #include "BankParameters.h" 10 | 11 | class UserTool { 12 | 13 | public: 14 | UserTool(int st, int l, const BankParameters *bp, 15 | const VEPublicKey &arbiterVPK, const VEPublicKey &arbiterPK, 16 | const hashalg_t &ha); 17 | 18 | UserTool(const UserTool &o) 19 | : stat(o.stat), lx(o.lx), 20 | bankParameters(new BankParameters(*o.bankParameters)), 21 | vepk(o.vepk), pk(o.pk), userSecretKey(o.userSecretKey), 22 | userPublicKey(o.userPublicKey), hashAlg(o.hashAlg), 23 | idProof(o.idProof) {} 24 | 25 | UserTool(const char *fname, const BankParameters *bp, 26 | const char *fnameVEPK, const char *fnamePK) 27 | : bankParameters(new BankParameters(*bp)), vepk(fnameVEPK), pk(fnamePK) 28 | { loadFile(make_nvp("UserTool", *this), fname); } 29 | 30 | // XXX: this was causing a seg fault... 31 | //~UserTool() { delete bankParameters; } 32 | 33 | // getters 34 | ZZ getPublicKey() const { return userPublicKey; } 35 | const VEPublicKey *getVEPublicKey() const { return &vepk; } 36 | SigmaProof getIdentityProof() const { return idProof; } 37 | const BankParameters* getBankParameters() const { return bankParameters; } 38 | 39 | UserWithdrawTool* getWithdrawTool(int walletSize, int coinDenom) const { 40 | return new UserWithdrawTool(stat, lx, bankParameters, 41 | userPublicKey, userSecretKey, 42 | hashAlg, walletSize, coinDenom); 43 | } 44 | 45 | /* Factory functions for user */ 46 | Buyer* getBuyer(time_t timeout) const 47 | { return new Buyer(timeout, &vepk, stat); } 48 | 49 | Seller* getSeller(time_t timeout, int timeoutTolerance) const 50 | { return new Seller(timeout, timeoutTolerance, &vepk, stat); } 51 | 52 | Seller* getSeller(EncBuffer* ctext, int t, int timeoutTolerance) const 53 | { return new Seller(ctext, t, timeoutTolerance, &vepk, stat); } 54 | 55 | FEInitiator* getFEInitiator(time_t timeout) const 56 | { return new FEInitiator(timeout, &vepk, &pk, stat); } 57 | 58 | FEResponder* getFEResponder(time_t t, int tolerance) const 59 | { return new FEResponder(t, tolerance, &vepk, &pk, stat); } 60 | 61 | private: 62 | int stat, lx; 63 | const BankParameters *bankParameters; 64 | VEPublicKey vepk; 65 | VEPublicKey pk; 66 | ZZ userSecretKey; 67 | ZZ userPublicKey; 68 | hashalg_t hashAlg; 69 | SigmaProof idProof; 70 | 71 | friend class boost::serialization::access; 72 | template 73 | void serialize(Archive& ar, const unsigned int ver) { 74 | ar & auto_nvp(stat) 75 | & auto_nvp(lx) 76 | // userKeyGroup, repk & vepk are loaded in 77 | // UserTool(fname, params, vepk, repk) constructor 78 | & auto_nvp(userSecretKey) // XXX should be encrypted 79 | & auto_nvp(userPublicKey) 80 | & auto_nvp(hashAlg) 81 | & auto_nvp(idProof); 82 | } 83 | }; 84 | 85 | #endif /*_USERTOOL_H_*/ 86 | -------------------------------------------------------------------------------- /src/UserWithdrawTool.h: -------------------------------------------------------------------------------- 1 | #ifndef USERWITHDRAWTOOL_H_ 2 | #define USERWITHDRAWTOOL_H_ 3 | 4 | #include "Wallet.h" 5 | #include "SigmaProof.h" 6 | #include "CLBlindRecipient.h" 7 | #include "BankParameters.h" 8 | 9 | /*! \brief This class is used for carrying out the user's side of the 10 | * withdraw protocol */ 11 | 12 | class UserWithdrawTool { 13 | 14 | public: 15 | UserWithdrawTool(int stat, int lx, const BankParameters *bp, 16 | const ZZ &userPK, const ZZ &userSK, 17 | const hashalg_t &hashAlg, int walletSize, int denom); 18 | 19 | UserWithdrawTool(const UserWithdrawTool &original); 20 | 21 | ~UserWithdrawTool(); 22 | 23 | /*! stores the vector 24 | * (r_sku, A_sku, s', r_s', A_s', t, r_t, A_t) where : 25 | * r_sku = randomness in opening of commitment to user secret key 26 | * A_sku = commitment to user secret key 27 | * s' = first secret picked from Z*_prime order 28 | * r_s' = randomness in opening of commitment to s' 29 | * A_s' = commitment to s' 30 | * t = second secret picked from Z*_prime order 31 | * r_t = randomness in opening of commitment to t 32 | * A_t = commitment to t 33 | * 34 | * returns A_s' 35 | */ 36 | ZZ createPartialCommitment(); 37 | 38 | /*! returns a SigmaProof that the first secret in the commitment 39 | * C (from the CLBlindRecipient) is the user's secret Key */ 40 | ProofMessage* initiateSignature(const ZZ &bankContribution); 41 | 42 | /*! return individual commitments to private messages */ 43 | vector getIndividualCommitments(); 44 | 45 | /*! return randomized proof from signature recipient */ 46 | ProofMessage* getCLProof() const; 47 | 48 | /*! verifies bank's PoKoDLR of 1/e and returns signature if 49 | * it is valid */ 50 | vector verify(const ProofMessage &proofEInverse); 51 | 52 | /*! returns a wallet with signature from bank 53 | * will throw exception if bank has not proved knowledge 54 | * of 1/e */ 55 | Wallet getWallet(const vector &signature) const; 56 | 57 | ZZ getUserPublicKey() const { return userPublicKey; } 58 | int getDenomination() const { return coinDenom; } 59 | bool isVerified() const { return verified; } 60 | 61 | private: 62 | /*! creates and stores CLBlindRecipient that interacts with 63 | * the bank to get the signature on the user secret key, s, t, and the 64 | * wallet size */ 65 | void createSignatureRecipient(); 66 | 67 | /*! returns a SigmaProof that the A_sku commitment in the partial 68 | * commitment is the user's secret Key */ 69 | ProofMessage* preSignatureProof(); 70 | 71 | ZZ s; // stored so we can use it to get wallet 72 | int stat, lx; 73 | const BankParameters *bankParameters; 74 | const GroupPrime *userKeyGroup; 75 | 76 | ZZ userSecretKey; 77 | ZZ userPublicKey; 78 | 79 | hashalg_t hashAlg; 80 | int walletSize; 81 | int coinDenom; 82 | 83 | vector partialCommitment; 84 | ZZ bankContribution; 85 | 86 | CLBlindRecipient *signatureRecipient; 87 | 88 | // store whether or not bank's PoK of 1/e is valid 89 | bool verified; 90 | }; 91 | 92 | #endif /*_USERWITHDRAWTOOL_H_*/ 93 | -------------------------------------------------------------------------------- /src/VECiphertext.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef _VECIPHERTEXT_H_ 3 | #define _VECIPHERTEXT_H_ 4 | 5 | #include "SigmaProof.h" 6 | #include "ZKP/Environment.h" 7 | 8 | /*! \brief This class represents a verifiable escrow */ 9 | 10 | class VECiphertext { 11 | public: 12 | /*! text represents the ciphertext itself, com represents the 13 | * commitment that was the basis of the proof, p represents the 14 | * proof of correctness, rangeCs represents the commitments 15 | * to each of the secret x_is contained in com */ 16 | VECiphertext(const vector &text, const ZZ &com, 17 | const variable_map &publics, const SigmaProof &p) 18 | : ciphertext(text), commitment(com), 19 | publicVariables(publics), proof(p) {} 20 | 21 | /*! copy constructor */ 22 | VECiphertext(const VECiphertext &o) 23 | : ciphertext(o.ciphertext), commitment(o.commitment), 24 | publicVariables(o.publicVariables), proof(o.proof) {} 25 | 26 | VECiphertext(const string& s) { loadString(*this, s); } 27 | 28 | VECiphertext() 29 | : ciphertext(), commitment(0), publicVariables(), proof() {} 30 | 31 | // getters 32 | vector getCiphertext() const { return ciphertext; } 33 | ZZ getCommitment() const { return commitment; } 34 | SigmaProof getProof() const { return proof; } 35 | variable_map getPublics() const { return publicVariables; } 36 | 37 | private: 38 | vector ciphertext; 39 | ZZ commitment; 40 | variable_map publicVariables; 41 | SigmaProof proof; 42 | 43 | friend class boost::serialization::access; 44 | template 45 | void serialize(Archive& ar, const unsigned int ver) { 46 | ar & auto_nvp(ciphertext) 47 | & auto_nvp(commitment) 48 | & make_nvp("publicVars", publicVariables) 49 | & make_nvp("proof", proof) 50 | ; 51 | } 52 | }; 53 | 54 | #endif /*_VECIPHERTEXT_H_*/ 55 | -------------------------------------------------------------------------------- /src/VEDecrypter.h: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * this is a class to represent a decrypter for verifiable encryption 4 | * it will also be used as the arbiter for fair exchange 5 | * 6 | * because the decrypter is the TTP (and needs to know the secret key) the 7 | * setup (i.e. keygen) is also done in this class 8 | */ 9 | 10 | #ifndef _VEDECRYPTER_H_ 11 | #define _VEDECRYPTER_H_ 12 | 13 | #include "VEPublicKey.h" 14 | #include "VESecretKey.h" 15 | 16 | class VEDecrypter { 17 | public: 18 | /*! takes in some parameters and performs the key generator for 19 | * verifiable encryption - if no group is specified then an 20 | * appropriate RSA group will be created in the course of the setup */ 21 | VEDecrypter(const int m, const int modLength, const int stat); 22 | VEDecrypter(const int m, const int modLength, const int stat, 23 | GroupRSA* auxGroup); 24 | 25 | /*! also allow the setup to be done elsewhere and the decrypter to 26 | * just be handed the public/secret keys */ 27 | VEDecrypter(VEPublicKey *p, VESecretKey *s) : pk(p), sk(s) {} 28 | 29 | /*! copy constructor */ 30 | VEDecrypter(const VEDecrypter& o) : pk(o.pk), sk(o.sk) {} 31 | 32 | // destructor 33 | ~VEDecrypter() {} 34 | 35 | /*! given a ciphertext and the encryption label, returns the 36 | * plaintext value if the ciphertext was formed correctly */ 37 | vector decrypt(const vector &ciphertext, 38 | const string &label, const hashalg_t &hashAlg) const; 39 | 40 | // getters 41 | VEPublicKey* getPK() { return pk; } 42 | VESecretKey* getSK() { return sk; } 43 | 44 | private: 45 | /*! does the key generation for verifiable encryption (so sets the 46 | * public and secret keys) */ 47 | void setup(const int m, const int modLength, const int stat, 48 | GroupRSA* auxGroup); 49 | 50 | /*! creates a group with the appropriate number of generators and 51 | * modLength */ 52 | GroupRSA* createSecondGroup(const int m, const int modLength, 53 | const int stat); 54 | VEPublicKey *pk; 55 | VESecretKey *sk; 56 | }; 57 | 58 | #endif /*VEDECRYPTER_H_*/ 59 | -------------------------------------------------------------------------------- /src/VEProver.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef _VEPROVER_H_ 3 | #define _VEPROVER_H_ 4 | 5 | #include "VEPublicKey.h" 6 | #include "VECiphertext.h" 7 | 8 | /*! \brief this represents a class for proving that the ciphertext, 9 | * once decrypted, will correspond to the value contained in a 10 | * given commitment */ 11 | 12 | class VEProver { 13 | public: 14 | /*! constructor: takes in a VE public key as generated by the 15 | * arbiter (decrypter) */ 16 | VEProver(const VEPublicKey* pk) : pk(pk) {} 17 | 18 | /*! copy constructor */ 19 | VEProver(const VEProver& o) : pk(o.pk) {} 20 | 21 | /*! destructor */ 22 | ~VEProver() {} 23 | 24 | // XXX: should ultimately have another function that takes in 25 | // genNames for group, and then use ProgramMaker to make a VE 26 | // program that doesn't assuming input form of group 27 | 28 | /*! verifiable encryption takes in a commitment and the opening to 29 | * the commitment. it outputs a ciphertext such that, when the 30 | * ciphertext is decrypted, the value will correspond to the value 31 | * contained within the commitment. it also outputs a 32 | * proof that this is true. */ 33 | VECiphertext verifiableEncrypt(const ZZ &commitment, 34 | const vector &opening, 35 | const Group* grp, const string &label, 36 | const hashalg_t &hashAlg, int stat); 37 | 38 | vector encrypt(const vector &messages, const string &label, 39 | const hashalg_t &hashAlg, int stat); 40 | 41 | private: 42 | const VEPublicKey* pk; 43 | Environment env; 44 | }; 45 | 46 | #endif /*VEPROVER_H_*/ 47 | -------------------------------------------------------------------------------- /src/VEPublicKey.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef _VEPUBLICKEY_H_ 3 | #define _VEPUBLICKEY_H_ 4 | 5 | #include "GroupRSA.h" 6 | #include "Hash.h" 7 | 8 | /*! \brief This class represents the public key for a verifiable 9 | * encryption scheme */ 10 | 11 | class VEPublicKey { 12 | public: 13 | VEPublicKey() {} 14 | 15 | /*! takes and stores various elements of the public key */ 16 | VEPublicKey(const ZZ &bigN, const vector &aValues, const ZZ &b, 17 | const ZZ &d, const ZZ &e, const ZZ& f, 18 | const GroupRSA& group2, const hashalg_t& hashAlg, 19 | const string& hashKey) 20 | : secondGroup(group2), bigN(bigN), 21 | aValues(aValues), b(b), d(d), e(e), f(f), 22 | hashAlg(hashAlg), hashKey(hashKey) { secondGroup.clearSecrets(); } 23 | 24 | /*! copy constructor */ 25 | VEPublicKey(const VEPublicKey &o) 26 | : secondGroup(o.secondGroup), bigN(o.bigN), 27 | aValues(o.aValues), b(o.b), d(o.d), e(o.e), f(o.f), 28 | hashAlg(o.hashAlg), hashKey(o.hashKey) 29 | { secondGroup.clearSecrets(); } 30 | 31 | /*! constructor to load from file */ 32 | VEPublicKey(const char *fname) 33 | { loadFile(make_nvp("VEPublicKey", *this), fname); } 34 | 35 | // getters for all the values in the public key 36 | ZZ getN() const { return bigN; } 37 | vector getAValues() const { return aValues; } 38 | GroupRSA getSecondGroup() const { return secondGroup; } 39 | string getHashKey() const { return hashKey; } 40 | hashalg_t getHashAlg() const { return hashAlg; } 41 | ZZ getB() const { return b; } 42 | ZZ getD() const { return d; } 43 | ZZ getE() const { return e; } 44 | ZZ getF() const { return f; } 45 | 46 | void setHashKey(const string& newKey){ hashKey = newKey;} 47 | void setHashAlg(const hashalg_t& newAlg){ hashAlg = newAlg;} 48 | 49 | GroupRSA secondGroup; 50 | ZZ bigN; 51 | vector aValues; 52 | ZZ b, d, e, f; 53 | hashalg_t hashAlg; 54 | string hashKey; 55 | 56 | friend class boost::serialization::access; 57 | template 58 | void serialize(Archive& ar, const unsigned int ver) { 59 | ar & auto_nvp(secondGroup); 60 | ar & auto_nvp(bigN); 61 | ar & auto_nvp(aValues); 62 | ar & auto_nvp(b); 63 | ar & auto_nvp(d); 64 | ar & auto_nvp(e); 65 | ar & auto_nvp(f); 66 | ar & auto_nvp(hashAlg); 67 | ar & auto_nvp(hashKey); 68 | } 69 | }; 70 | 71 | #endif /*VEPUBLICKEY_H_*/ 72 | -------------------------------------------------------------------------------- /src/VESecretKey.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef _VESECRETKEY_H_ 3 | #define _VESECRETKEY_H_ 4 | 5 | #include 6 | #include "CommonFunctions.h" 7 | 8 | /*! \brief This class represents the secret key for a verifiable 9 | * encryption scheme */ 10 | 11 | class VESecretKey { 12 | public: 13 | /*! takes in various things to be stored - note that what we are 14 | * storing as y and z are the last two elements in xValues */ 15 | VESecretKey(ZZ bigP, ZZ bigQ, vector xValues, ZZ p, ZZ q) 16 | : bigP(bigP), bigQ(bigQ), p(p), q(q) { 17 | // don't want the entire vector, just up to last two elements 18 | unsigned m = xValues.size() - 2; 19 | xs = CommonFunctions::subvector(xValues, 0, m); 20 | y = xValues[m]; 21 | z = xValues[m+1]; 22 | } 23 | 24 | /*! copy constructor */ 25 | VESecretKey(const VESecretKey &o) 26 | : bigP(o.bigP), bigQ(o.bigQ), xs(o.xs), y(o.y), 27 | z(o.z), p(o.p), q(o.q) {} 28 | 29 | /*! Constructor to load from file */ 30 | VESecretKey(const char *fname) 31 | { loadFile(make_nvp("VESecretKey", *this), fname); } 32 | 33 | // list of getters for all values 34 | vector getXValues() const { return xs; } 35 | ZZ getBigP() const { return bigP; } 36 | ZZ getBigQ() const { return bigQ; } 37 | ZZ getY() const { return y; } 38 | ZZ getZ() const { return z; } 39 | ZZ getP() const { return p; } 40 | ZZ getQ() const { return q; } 41 | 42 | private: 43 | ZZ bigP, bigQ; 44 | vector xs; 45 | ZZ y, z; 46 | ZZ p, q; 47 | 48 | friend class boost::serialization::access; 49 | template 50 | void serialize(Archive& ar, const unsigned int ver) { 51 | ar & auto_nvp(bigP) & auto_nvp(bigQ) & auto_nvp(xs) 52 | & auto_nvp(y) & auto_nvp(z) 53 | & auto_nvp(p) & auto_nvp(q); 54 | } 55 | }; 56 | 57 | #endif /*VESECRETKEY_H_*/ 58 | -------------------------------------------------------------------------------- /src/VEVerifier.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "VEVerifier.h" 3 | #include "ZKP/InterpreterVerifier.h" 4 | #include "GroupSquareMod.h" 5 | #include "Timer.h" 6 | 7 | bool VEVerifier::verify(const VECiphertext& text, const ZZ& x, 8 | const Group *grp, const string& label, 9 | const hashalg_t& hashAlg, int stat) { 10 | // set everything up (a lot like the prover side) 11 | Environment env; 12 | env.variables["X"] = x; 13 | env.variables["Xprime"] = text.getCommitment(); 14 | // also add a values 15 | vector as = pk->getAValues(); 16 | for (unsigned i = 0; i < as.size(); i++) { 17 | string name = "a_" + lexical_cast(i+1); 18 | env.variables[name] = as[i]; 19 | } 20 | env.variables["b"] = pk->getB(); 21 | env.variables["d"] = pk->getD(); 22 | env.variables["e"] = pk->getE(); 23 | env.variables["f"] = pk->getF(); 24 | 25 | // set up all groups 26 | env.groups["cashGroup"] = grp; 27 | ZZ bigN = pk->getN(); 28 | env.groups["RSAGroup"] = new GroupRSA("arbiter", bigN, stat); 29 | ZZ bigNSquared = power(bigN, 2); 30 | env.groups["G"] = new GroupSquareMod("arbiter", bigNSquared, stat); 31 | const GroupRSA* second = new GroupRSA(pk->getSecondGroup()); 32 | env.groups["secondGroup"] = second; 33 | input_map inputs; 34 | inputs["m"] = text.getCiphertext().size() - 2; 35 | 36 | // okay, now that everything is all set, just run the program 37 | SigmaProof proof = text.getProof(); 38 | variable_map publics = text.getPublics(); 39 | InterpreterVerifier verifier; 40 | verifier.check(CommonFunctions::getZKPDir()+"/ve.txt", inputs, env.groups); 41 | verifier.compute(env.variables, proof.getCommitments(), publics); 42 | return verifier.verify(proof, stat); 43 | } 44 | -------------------------------------------------------------------------------- /src/VEVerifier.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef _VEVERIFIER_H_ 3 | #define _VEVERIFIER_H_ 4 | 5 | #include "VEPublicKey.h" 6 | #include "VECiphertext.h" 7 | 8 | class VEVerifier { 9 | public: 10 | /*! constructor takes in the decrypter's public key */ 11 | VEVerifier(const VEPublicKey *pk) : pk(pk) {} 12 | 13 | /*! copy constructor */ 14 | VEVerifier(const VEVerifier &original) : pk(original.pk) {} 15 | 16 | /*! destructor */ 17 | ~VEVerifier() {} 18 | 19 | /*! given the output of a VEProver, checks to see that it is correct 20 | * (i.e. accepts or rejects the proof that the value contained in the 21 | * ciphertext corresponds to the opening of commitment x) */ 22 | bool verify(const VECiphertext &text, const ZZ &x, const Group* grp, 23 | const string &label, const hashalg_t &hashAlg, int stat); 24 | 25 | private: 26 | const VEPublicKey* pk; 27 | }; 28 | 29 | #endif /*_VEVERIFIER_H_*/ 30 | -------------------------------------------------------------------------------- /src/Wallet.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "Wallet.h" 3 | 4 | Wallet::Wallet(const ZZ &sk, const ZZ &sIn, const ZZ &tIn, int size, 5 | int d, const BankParameters* bp, int st, int l, 6 | const hashalg_t &alg, const vector &sig) 7 | : sk_u(sk), s(sIn), t(tIn), walletSize(size), coinDenom(d), 8 | numCoinsUsed(0), params(bp), stat(st), lx(l), hashAlg(alg), 9 | signature(sig) 10 | { 11 | // generate a list of the indices that haven't yet been added to 12 | // the spendOrder vector 13 | for(int i = 0; i < walletSize; i++) { 14 | //spendOrder[i] = i; 15 | spendOrder.push_back(i); 16 | } 17 | 18 | // fill the spendOrder vector 19 | // On iteration i, remaining free indices are values 20 | // remainingIndices[0], ..., remainingIndices[walletSize - i - 1] 21 | for(int i = 0; i < walletSize; i++) { 22 | int index = RandomBnd(walletSize); 23 | int temp = spendOrder[i]; 24 | spendOrder[i] = spendOrder[index]; 25 | spendOrder[index] = temp; 26 | } 27 | #ifdef DEBUG 28 | for(int i = 0; i < walletSize; i++) { 29 | cout << spendOrder[i] << " "; 30 | } 31 | #endif //DEBUG 32 | } 33 | 34 | Wallet::Wallet(const Wallet &o) 35 | : sk_u(o.sk_u), s(o.s), t(o.t), walletSize(o.walletSize), 36 | coinDenom(o.coinDenom), numCoinsUsed(o.numCoinsUsed), params(o.params), 37 | stat(o.stat), lx(o.lx), hashAlg(o.hashAlg), signature(o.signature), 38 | spendOrder(o.spendOrder) 39 | { 40 | } 41 | 42 | int Wallet::nextCoinIndex() { 43 | if(numCoinsUsed >= walletSize) { 44 | throw CashException(CashException::CE_UNKNOWN_ERROR, 45 | "Tried to get the next coin from a wallet from which every " 46 | "coin had already been spent"); 47 | } 48 | return spendOrder[numCoinsUsed++]; 49 | } 50 | 51 | Coin Wallet::nextCoin(const ZZ &rValue) { 52 | int i = nextCoinIndex(); 53 | Coin* c = newCoin(rValue, i); 54 | Coin ret(*c); 55 | delete c; 56 | return ret; 57 | } 58 | 59 | Coin* Wallet::newCoin(const ZZ &rValue, int coinIndex) { 60 | return new Coin(params, walletSize, coinIndex, 61 | sk_u, s, t, signature, stat, 62 | lx, rValue, coinDenom, hashAlg); 63 | } 64 | 65 | void Wallet::newCoin(Coin& coin, const ZZ &rValue, int coinIndex) { 66 | coin = Coin(params, walletSize, coinIndex, 67 | sk_u, s, t, signature, stat, 68 | lx, rValue, coinDenom, hashAlg); 69 | } 70 | 71 | bool Wallet::replaceCoin(ZZ &index) { 72 | // check that 0 <= indexArg < walletSize 73 | if(index < 0 || index >= walletSize) { 74 | return false; 75 | } 76 | 77 | // search through "coin spend order" to see if that coin index has been 78 | // withdrawn yet or not 79 | for(unsigned i = numCoinsUsed; i < spendOrder.size(); i++) { 80 | if(spendOrder[i] == index) { 81 | return false; 82 | } 83 | } 84 | numCoinsUsed--; 85 | spendOrder[numCoinsUsed] = to_int(index); 86 | return true; 87 | } 88 | -------------------------------------------------------------------------------- /src/Wallet.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef _WALLET_H_ 3 | #define _WALLET_H_ 4 | 5 | #include "Coin.h" 6 | 7 | class Wallet { 8 | 9 | public: 10 | Wallet(const ZZ &sk, const ZZ &sIn, const ZZ &tIn, int size, 11 | int d, const BankParameters* b, int st, int l, 12 | const hashalg_t &alg, const vector &sig); 13 | 14 | Wallet(const Wallet &o); 15 | 16 | /*! constructor to load from file */ 17 | Wallet(const char* fname, const BankParameters* bp) 18 | : params(bp) 19 | { loadFile(make_nvp("Wallet", *this), fname); } 20 | 21 | /*! gets the next index for the coin 22 | * this increments the numCoinsUsed counter by one */ 23 | int nextCoinIndex(); 24 | 25 | /*! returns the next coin to use */ 26 | Coin nextCoin(const ZZ &R); 27 | 28 | /*! returns a coin for a given index */ 29 | Coin* newCoin(const ZZ &R, int coinIndex); 30 | void newCoin(Coin& coin, const ZZ &R, int coinIndex); 31 | 32 | bool replaceCoin(ZZ &index); 33 | 34 | // some accessors 35 | int getWalletSize() const { return walletSize; } 36 | int getNumCoinsUsed() const { return numCoinsUsed; } 37 | int getNumCoinsLeft() const { return walletSize - numCoinsUsed; } 38 | int getDenomination() const { return coinDenom; } 39 | int getRemainingValue() const { return getNumCoinsLeft() * coinDenom; } 40 | bool empty() const { return (walletSize == numCoinsUsed); } 41 | 42 | private: 43 | ZZ sk_u, s, t; 44 | int walletSize; 45 | int coinDenom; 46 | int numCoinsUsed; 47 | 48 | const BankParameters* params; 49 | int stat; 50 | int lx; 51 | hashalg_t hashAlg; 52 | vector signature; 53 | vector spendOrder; 54 | 55 | friend class boost::serialization::access; 56 | template 57 | void serialize(Archive& ar, const unsigned int ver) { 58 | ar & auto_nvp(sk_u) // XXX: should be encrypted 59 | & auto_nvp(s) 60 | & auto_nvp(t) 61 | & auto_nvp(walletSize) 62 | & auto_nvp(coinDenom) 63 | & auto_nvp(numCoinsUsed) 64 | & auto_nvp(stat) 65 | & auto_nvp(lx) 66 | & auto_nvp(hashAlg) 67 | & auto_nvp(signature) 68 | & auto_nvp(spendOrder) 69 | ; 70 | } 71 | }; 72 | 73 | #endif /*_WALLET_H_*/ 74 | -------------------------------------------------------------------------------- /src/ZKP/.cvsignore: -------------------------------------------------------------------------------- 1 | .deps *.d 2 | test 3 | -------------------------------------------------------------------------------- /src/ZKP/ASTHVisitor.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef ASTHVISITOR_H_ 3 | #define ASTHVISITOR_H_ 4 | 5 | #include "ASTVisitor.h" 6 | #include "ASTNode.h" 7 | 8 | class ASTHVisitor : public ASTVisitor { 9 | 10 | public: 11 | void applyASTNode(ASTNodePtr n){} 12 | 13 | //Lists 14 | void applyASTList(ASTListPtr n){ applyASTNode(dynamic_pointer_cast(n)); } 15 | void applyASTListIdentifierLit(ASTListIdentifierLitPtr n){applyASTList(n);} 16 | void applyASTListIdentifierSub(ASTListIdentifierSubPtr n){applyASTList(n);} 17 | void applyASTListDeclIdentifierLit(ASTListDeclIdentifierLitPtr n){applyASTList(n);} 18 | void applyASTListDeclIdentifierSub(ASTListDeclIdentifierSubPtr n){applyASTList(n);} 19 | void applyASTListRelation(ASTListRelationPtr n){applyASTList(n);} 20 | void applyASTListGiven(ASTListGivenPtr n){applyASTList(n);} 21 | void applyASTListRandoms(ASTListRandomsPtr n){applyASTList(n);} 22 | void applyASTListDecl(ASTListDeclPtr n){applyASTList(n);} 23 | void applyASTDeclIDRange(ASTDeclIDRangePtr n){applyASTNode(n);} 24 | 25 | //Expressions 26 | void applyASTExpr(ASTExprPtr n){applyASTNode(n);} 27 | void applyASTExprInt(ASTExprIntPtr n){applyASTExpr(n);} 28 | void applyASTExprIdentifier(ASTExprIdentifierPtr n){applyASTExpr(n);} 29 | void applyASTUnaryOp(ASTUnaryOpPtr n){applyASTExpr(n);} 30 | void applyASTBinaryOp(ASTBinaryOpPtr n){applyASTExpr(n);} 31 | 32 | void applyASTForExpr(ASTForExprPtr n){applyASTNode(n);} 33 | void applyASTForRel(ASTForRelPtr n){applyASTNode(n);} 34 | 35 | void applyASTNegative(ASTNegativePtr n){applyASTUnaryOp(n);} 36 | 37 | void applyASTPow(ASTPowPtr n){applyASTBinaryOp(n);} 38 | void applyASTMul(ASTMulPtr n){applyASTBinaryOp(n);} 39 | void applyASTDiv(ASTDivPtr n){applyASTBinaryOp(n);} 40 | void applyASTAdd(ASTAddPtr n){applyASTBinaryOp(n);} 41 | void applyASTSub(ASTSubPtr n){applyASTBinaryOp(n);} 42 | 43 | //Relations 44 | void applyASTRelation(ASTRelationPtr n){applyASTNode(n);} 45 | void applyASTEqual(ASTEqualPtr n){applyASTRelation(n);} 46 | void applyASTCommitment(ASTCommitmentPtr n){applyASTRelation(n);} 47 | void applyASTRange(ASTRangePtr n){applyASTRelation(n);} 48 | void applyASTDeclEqual(ASTDeclEqualPtr n) {applyASTRelation(n);} 49 | void applyASTRandomBnd(ASTRandomBndPtr n){applyASTNode(n);} 50 | void applyASTRandomPrime(ASTRandomPrimePtr n){applyASTNode(n);} 51 | 52 | //Declarations 53 | void applyASTDeclIdentifierLit(ASTDeclIdentifierLitPtr n){applyASTNode(n);} 54 | void applyASTDeclIdentifierSub(ASTDeclIdentifierSubPtr n){applyASTNode(n);} 55 | 56 | //"Given" Constructions 57 | void applyASTGiven(ASTGivenPtr n){applyASTNode(n);} 58 | void applyASTDeclElements(ASTDeclElementsPtr n){applyASTGiven(n);} 59 | void applyASTDeclExponents(ASTDeclExponentsPtr n){applyASTGiven(n);} 60 | void applyASTDeclGroup(ASTDeclGroupPtr n){applyASTGiven(n);} 61 | void applyASTDeclIntegers(ASTDeclIntegersPtr n){applyASTGiven(n);} 62 | void applyASTDeclRandExponents(ASTDeclRandExponentsPtr n) {applyASTGiven(n);} 63 | 64 | //The Core Constructions 65 | void applyASTProof(ASTProofPtr n){applyASTNode(n);} 66 | void applyASTComputation(ASTComputationPtr n){applyASTNode(n);} 67 | void applyASTSpec(ASTSpecPtr n){applyASTNode(n);} 68 | 69 | //Other 70 | void applyASTIdentifierLit(ASTIdentifierLitPtr n){applyASTNode(n);} 71 | void applyASTIdentifierSub(ASTIdentifierSubPtr n){applyASTNode(n);} 72 | }; 73 | 74 | #endif /*ASTHVISITOR_H_*/ 75 | -------------------------------------------------------------------------------- /src/ZKP/ASTTVisitor.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef ASTTVISITOR_H_ 3 | #define ASTTVISITOR_H_ 4 | 5 | #include "ASTHVisitor.h" 6 | 7 | class ASTTVisitor : public ASTHVisitor { 8 | public: 9 | void applyASTNode(ASTNodePtr n){ 10 | n->visitChildren(*this); 11 | } 12 | }; 13 | 14 | #endif /*ASTTVISITOR_H_*/ 15 | -------------------------------------------------------------------------------- /src/ZKP/BindGroupValues.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "BindGroupValues.h" 3 | #include "../Group.h" 4 | #include "Environment.h" 5 | 6 | void BindGroupValues::applyASTDeclGroup(ASTDeclGroupPtr n) { 7 | 8 | string grpname = n->getGroup()->getName(); 9 | const Group* grp = env.groups.at(grpname); 10 | ASTListDeclPtr gens = n->getItems(); 11 | 12 | // first bind modulus if it has been specified 13 | ASTDeclIdentifierSubPtr modName = n->getModulus(); 14 | if (modName != 0) { 15 | ZZ mod = grp->getModulus(); 16 | env.variables[modName->getName()] = mod; 17 | } 18 | 19 | // only need to do generators if they were specified 20 | int offset = 0; 21 | if (gens) { 22 | ASTDeclIdentifierSubPtr id; 23 | ASTDeclIDRangePtr idRange; 24 | for (int i = 0; i < gens->size(); i++) { 25 | ASTNodePtr ith = gens->get(i); 26 | if ((id=dynamic_pointer_cast(ith)) != 0) { 27 | // associate generator with its value 28 | string name = id->getName(); 29 | env.variables[name] = grp->getGenerator(i+offset); 30 | // XXX: for now just using a dummy value since I don't 31 | // care, I just care if it's in the map or not 32 | env.generators[name] = 1; 33 | } else if((idRange=dynamic_pointer_cast(ith))!=0){ 34 | for(int x = idRange->getLBound(); x<=idRange->getUBound(); x++){ 35 | // associate generator with its value 36 | string name = idRange->getName(x); 37 | env.variables[name] = grp->getGenerator(i+offset); 38 | env.generators[name] = 1; 39 | offset++; 40 | } 41 | // in the last iteration, we don't want to increase offset 42 | // because i will be increased, so we need to compensate 43 | offset--; 44 | } else{ 45 | throw CashException(CashException::CE_PARSE_ERROR, 46 | "Variable %d was not a valid declaration", i); 47 | } 48 | } 49 | } 50 | } 51 | 52 | void BindGroupValues::apply(ASTNodePtr n) { 53 | n->visit(*this); 54 | } 55 | 56 | 57 | 58 | -------------------------------------------------------------------------------- /src/ZKP/BindGroupValues.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef _BINDGROUPVALUES_H_ 3 | #define _BINDGROUPVALUES_H_ 4 | 5 | #include "ASTNode.h" 6 | #include "ASTTVisitor.h" 7 | 8 | /*! 9 | * \brief Used to associate generators with their actual values 10 | */ 11 | 12 | class BindGroupValues : public ASTTVisitor { 13 | 14 | public: 15 | /*! this visitor is used only after user has given actual values */ 16 | BindGroupValues(Environment &e) : env(e) {} 17 | 18 | /*! map each generator to its numeric value */ 19 | void applyASTDeclGroup(ASTDeclGroupPtr n); 20 | 21 | /*! map all generators to their values in the groups */ 22 | void apply(ASTNodePtr n); 23 | 24 | private: 25 | Environment &env; 26 | }; 27 | 28 | #endif /*_BINDGROUPVALUES_H_*/ 29 | -------------------------------------------------------------------------------- /src/ZKP/CommitmentVisitor.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "CommitmentVisitor.h" 3 | #include "DescribeRelations.h" 4 | 5 | void CommitmentVisitor::applyASTCommitment(ASTCommitmentPtr n) { 6 | 7 | ASTListIdentifierSubPtr vals = n->getComs(); 8 | ASTIdentifierSubPtr com = n->getId(); 9 | ASTExprPtr dlr = n->getExpr(); 10 | string comName = com->getName(); 11 | 12 | // need to get real DLR to put in map 13 | ASTEqualPtr eq = new_ptr(com, dlr); 14 | DLRepresentation rep = DescribeRelations::splitExpr(eq, env); 15 | 16 | // add DL form of the commitment in here 17 | env.discreteLogs[comName] = rep; 18 | 19 | ASTIdentifierSubPtr name; 20 | for (int i = 0; i < vals->size(); i++) { 21 | name = dynamic_pointer_cast(vals->get(i)); 22 | // problem if it's not id or if it's not in the map 23 | if (name == 0 || env.varTypes.count(name->getName()) == 0) 24 | throw CashException(CashException::CE_PARSE_ERROR, 25 | "Variable %d was not a valid name", i); 26 | env.commitments[name->getName()] = comName; 27 | } 28 | } 29 | 30 | void CommitmentVisitor::apply(ASTNodePtr n) { 31 | n->visit(*this); 32 | } 33 | -------------------------------------------------------------------------------- /src/ZKP/CommitmentVisitor.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef _COMMITMENTVISITOR_H_ 3 | #define _COMMITMENTVISITOR_H_ 4 | 5 | #include "ASTNode.h" 6 | #include "ASTTVisitor.h" 7 | 8 | /*! 9 | * \brief This class is used for describing the form of commitments and for 10 | * associating the names of the commitments with the names of the values 11 | * inside 12 | */ 13 | 14 | class CommitmentVisitor : public ASTTVisitor { 15 | 16 | public: 17 | /*! this visitor is used before the user gives actual values */ 18 | CommitmentVisitor(Environment &e) : env(e) {} 19 | 20 | /*! associate values inside of a commitment to the commitment name; 21 | * also associate commitment name to its DLR */ 22 | void applyASTCommitment(ASTCommitmentPtr n); 23 | 24 | /*! describes all commitments */ 25 | void apply(ASTNodePtr n); 26 | 27 | private: 28 | Environment &env; 29 | 30 | }; 31 | 32 | #endif /*_COMMITMENTVISITOR_H_*/ 33 | 34 | 35 | -------------------------------------------------------------------------------- /src/ZKP/ComputationVisitor.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef _COMPUTATIONVISITOR_H_ 3 | #define _COMPUTATIONVISITOR_H_ 4 | 5 | #include "ASTTVisitor.h" 6 | #include "ASTNode.h" 7 | 8 | /*! 9 | * \brief This visitor carries out the instructions for the computation 10 | * block and stores the results 11 | */ 12 | 13 | class ComputationVisitor : public ASTTVisitor { 14 | 15 | public: 16 | /*! this visitor is used after the user gives us real values */ 17 | ComputationVisitor(Environment &e) : env(e) {} 18 | 19 | /*! compute all random values needed */ 20 | void applyASTDeclRandExponents(ASTDeclRandExponentsPtr n); 21 | void applyASTRandomBnd(ASTRandomBndPtr n); 22 | void applyASTRandomPrime(ASTRandomPrimePtr n); 23 | 24 | /*! computes commitments and other DLR forms; will throw exception 25 | * if unable to perform computation (i.e. b/c mismatched groups) */ 26 | void applyASTDeclEqual(ASTDeclEqualPtr n); 27 | 28 | /*! performs all computations described in computation block and 29 | * stores new variables in the environment */ 30 | void apply(ASTNodePtr n); 31 | 32 | private: 33 | Environment &env; 34 | }; 35 | 36 | #endif /*_COMPUTATIONVISITOR_H_*/ 37 | -------------------------------------------------------------------------------- /src/ZKP/ConstantProp.cpp: -------------------------------------------------------------------------------- 1 | #include "ConstantProp.h" 2 | 3 | void ConstantProp::applyASTForExpr(ASTForExprPtr n){ 4 | ZZ result; 5 | Environment e; 6 | ASTExprIntPtr ne; 7 | try{ 8 | result = n->getLBound()->eval(e); 9 | ne = new_ptr(result); 10 | n->setLBound(ne); 11 | } catch(std::out_of_range e){ 12 | n->getLBound()->visit(*this); 13 | } 14 | try{ 15 | result = n->getUBound()->eval(e); 16 | ne = new_ptr(result); 17 | n->setUBound(ne); 18 | } catch(std::out_of_range e){ 19 | n->getUBound()->visit(*this); 20 | } 21 | try{ 22 | result = n->getExpr()->eval(e); 23 | ne = new_ptr(result); 24 | n->setExpr(ne); 25 | } catch(std::out_of_range e){ 26 | n->getExpr()->visit(*this); 27 | } 28 | } 29 | 30 | void ConstantProp::applyASTForRel(ASTForRelPtr n){ 31 | ZZ result; 32 | Environment e; 33 | ASTExprIntPtr ne; 34 | try{ 35 | result = n->getLBound()->eval(e); 36 | ne = new_ptr(result); 37 | n->setLBound(ne); 38 | } catch(std::out_of_range e){ 39 | n->getLBound()->visit(*this); 40 | } 41 | try{ 42 | result = n->getUBound()->eval(e); 43 | ne = new_ptr(result); 44 | n->setUBound(ne); 45 | } catch(std::out_of_range e){ 46 | n->getUBound()->visit(*this); 47 | } 48 | } 49 | 50 | void ConstantProp::applyASTDeclIDRange(ASTDeclIDRangePtr n){ 51 | ZZ result; 52 | Environment e; 53 | ASTExprIntPtr ne; 54 | try{ 55 | result = n->getLP()->eval(e); 56 | ne = new_ptr(result); 57 | n->setLBound(ne); 58 | } catch(std::out_of_range e){ 59 | n->getLP()->visit(*this); 60 | } 61 | try{ 62 | result = n->getUP()->eval(e); 63 | ne = new_ptr(result); 64 | n->setUBound(ne); 65 | } catch(std::out_of_range e){ 66 | n->getUP()->visit(*this); 67 | } 68 | } 69 | 70 | void ConstantProp::applyASTBinaryOp(ASTBinaryOpPtr n){ 71 | ZZ result; 72 | Environment e; 73 | ASTExprIntPtr ne; 74 | try{ 75 | result = n->getLHS()->eval(e); 76 | ne = new_ptr(result); 77 | n->setLHS(ne); 78 | } catch(std::out_of_range e){ 79 | n->getLHS()->visit(*this); 80 | } 81 | try{ 82 | result = n->getRHS()->eval(e); 83 | ne = new_ptr(result); 84 | n->setRHS(ne); 85 | } catch(std::out_of_range e){ 86 | n->getRHS()->visit(*this); 87 | } 88 | } 89 | 90 | void ConstantProp::applyASTUnaryOp(ASTUnaryOpPtr n){ 91 | ZZ result; 92 | Environment e; 93 | try{ 94 | result = n->getExpr()->eval(e); 95 | ASTExprIntPtr ne = new_ptr(result); 96 | n->setExpr(ne); 97 | } catch(std::out_of_range e){ 98 | n->getExpr()->visit(*this); 99 | } 100 | } 101 | 102 | -------------------------------------------------------------------------------- /src/ZKP/ConstantProp.h: -------------------------------------------------------------------------------- 1 | #ifndef __CONSTANTPROP_H__ 2 | #define __CONSTANTPROP_H__ 3 | 4 | #include "ASTNode.h" 5 | #include "ASTTVisitor.h" 6 | #include 7 | #include "Environment.h" 8 | 9 | class ConstantProp : public ASTTVisitor{ 10 | 11 | public: 12 | ConstantProp(input_map &i) : inputs(i), newConstant(true) {} 13 | 14 | void applyASTForExpr(ASTForExprPtr n); 15 | void applyASTForRel(ASTForRelPtr n); 16 | void applyASTDeclIDRange(ASTDeclIDRangePtr n); 17 | void applyASTRange(ASTRangePtr n) {} 18 | void applyASTCommitment(ASTCommitmentPtr n) {} 19 | void applyASTEqual(ASTEqualPtr n) {} 20 | void applyASTDeclEqual(ASTDeclEqualPtr n) {} 21 | void applyASTBinaryOp(ASTBinaryOpPtr n); 22 | void applyASTUnaryOp(ASTUnaryOpPtr n); 23 | void applyASTRandomBnd(ASTRandomBndPtr n) {} 24 | void applyASTRandomPrime(ASTRandomPrimePtr n) {} 25 | 26 | bool subAgain(){return newConstant;} 27 | void reset(){newConstant=false;} 28 | 29 | private: 30 | input_map &inputs; 31 | bool newConstant; 32 | }; 33 | 34 | #endif /* __CONSTANTPROP_H__*/ 35 | -------------------------------------------------------------------------------- /src/ZKP/ConstantSub.h: -------------------------------------------------------------------------------- 1 | #ifndef __CONSTANTSUB_H__ 2 | #define __CONSTANTSUB_H__ 3 | 4 | #include "ASTNode.h" 5 | #include "ASTTVisitor.h" 6 | #include "Environment.h" 7 | 8 | class ConstantSub : public ASTTVisitor{ 9 | 10 | public: 11 | ConstantSub(input_map &i) : inputs(i), newConstant(true) {} 12 | 13 | void applyASTForExpr(ASTForExprPtr n); 14 | void applyASTForRel(ASTForRelPtr n); 15 | void applyASTDeclIDRange(ASTDeclIDRangePtr n); 16 | void applyASTRange(ASTRangePtr n); 17 | void applyASTCommitment(ASTCommitmentPtr n); 18 | void applyASTEqual(ASTEqualPtr n); 19 | void applyASTDeclEqual(ASTDeclEqualPtr n); 20 | void applyASTBinaryOp(ASTBinaryOpPtr n); 21 | void applyASTUnaryOp(ASTUnaryOpPtr n); 22 | void applyASTIdentifierSub(ASTIdentifierSubPtr n); 23 | void applyASTDeclIdentifierSub(ASTDeclIdentifierSubPtr n); 24 | void applyASTRandomBnd(ASTRandomBndPtr n); 25 | void applyASTRandomPrime(ASTRandomPrimePtr n); 26 | 27 | bool anotherPass(){ return newConstant; } 28 | void reset(){newConstant=false;} 29 | 30 | private: 31 | input_map &inputs; 32 | bool newConstant; 33 | }; 34 | 35 | #endif /* _CONSTANTSUB_H_*/ 36 | -------------------------------------------------------------------------------- /src/ZKP/DLRepresentation.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "DLRepresentation.h" 3 | #include "MultiExp.h" 4 | #include 5 | #include "Environment.h" 6 | #include "Printer.h" 7 | 8 | DLRepresentation::DLRepresentation(const DLRepresentation &o) 9 | : left(o.left), group(o.group), bases(o.bases), exps(o.exps) 10 | { 11 | } 12 | 13 | string DLRepresentation::toString() const { 14 | string toReturn = ""; 15 | toReturn += left->toString() + " = "; 16 | 17 | assert(bases.size() == exps.size()); 18 | for (unsigned i = 0; i < bases.size(); i++) { 19 | toReturn += "(" + bases[i]->toString() + ")^(" + 20 | exps[i]->toString() + ")"; 21 | } 22 | toReturn += " in " + group; 23 | return toReturn; 24 | } 25 | 26 | vector DLRepresentation::getBaseNames() const { 27 | vector names; 28 | for (unsigned i = 0; i < bases.size(); i++) { 29 | names.push_back(bases[i]->toString()); 30 | } 31 | return names; 32 | } 33 | 34 | int DLRepresentation::randIndex(Environment &env) const { 35 | assert(exps.size() == 2); 36 | return (env.commitments.count(exps[0]->toString()) == 0) ? 0 : 1; 37 | } 38 | 39 | ZZ DLRepresentation::computeValue(Environment &env) const { 40 | assert(bases.size() == exps.size()); 41 | ZZ mod = env.groups.at(group)->getModulus(); 42 | vector bs, es; 43 | vector baseNames; 44 | for (unsigned i = 0; i < bases.size(); i++) { 45 | ZZ b = bases[i]->eval(env), e = exps[i]->eval(env); 46 | bs.push_back(b); 47 | es.push_back(e); 48 | baseNames.push_back(bases[i]->toString()); 49 | } 50 | if (bases.size() == 1) 51 | return env.modPow(baseNames[0], bs[0], es[0], mod); 52 | else 53 | return env.multiExp(baseNames, bs, es, mod); 54 | } 55 | -------------------------------------------------------------------------------- /src/ZKP/DLRepresentation.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef _DLREPRESENTATION_H_ 3 | #define _DLREPRESENTATION_H_ 4 | 5 | #include "ASTNode.h" 6 | 7 | class Environment; 8 | 9 | class DLRepresentation { 10 | 11 | public: 12 | DLRepresentation() {} 13 | 14 | DLRepresentation(const DLRepresentation &o); 15 | 16 | int randIndex(Environment &env) const; 17 | ASTExprPtr commitExp(Environment &env) const 18 | { return exps[(randIndex(env) + 1) % 2]; } 19 | ASTExprPtr randExp(Environment &env) const 20 | { return exps[randIndex(env)]; } 21 | ASTExprPtr base(Environment &env) const 22 | { return bases[(randIndex(env) + 1) % 2]; } 23 | ASTExprPtr randBase(Environment &env) const 24 | { return bases[randIndex(env)]; } 25 | 26 | ZZ computeValue(Environment &env) const; 27 | string toString() const; 28 | vector getBaseNames() const; 29 | 30 | ASTExprIdentifierPtr left; 31 | string group; 32 | vector bases; 33 | vector exps; 34 | 35 | private: 36 | friend class boost::serialization::access; 37 | template 38 | void serialize(Archive& ar, const unsigned int ver) { 39 | ar & auto_nvp(left) 40 | & auto_nvp(group) 41 | & auto_nvp(bases) 42 | & auto_nvp(exps) 43 | ; 44 | } 45 | }; 46 | 47 | #endif /*_DLREPRESENTATION_H_*/ 48 | -------------------------------------------------------------------------------- /src/ZKP/DescribeRelations.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef _DESCRIBERELATIONS_H_ 3 | #define _DESCRIBERELATIONS_H_ 4 | 5 | #include "ASTTVisitor.h" 6 | #include "Translator.h" 7 | #include "DLRepresentation.h" 8 | 9 | class DescribeRelations : public ASTTVisitor { 10 | 11 | public: 12 | DescribeRelations(Environment &e) : env(e), translator(e) {} 13 | 14 | /*! an ASTEqual can represent three of our relations: 15 | * multiplication, square, or DLR. we check types and forms of 16 | * the DLR to infer which one it is, and then call the appropriate 17 | * translation function to get down to base flexible equality form */ 18 | void applyASTEqual(ASTEqualPtr n); 19 | 20 | /*! find appropriate commitment descriptions for value in a range 21 | * and use them to create flexible equality DLRs */ 22 | void applyASTRange(ASTRangePtr n); 23 | 24 | /*! this will split an expression of the form g^x * h^r_x into 25 | * its representation as vectors of bases and exponents */ 26 | static DLRepresentation splitExpr(ASTEqualPtr n, Environment &env); 27 | 28 | /*! breaks all the relations in the 'such that' block down 29 | * into flexible equality form */ 30 | void apply(ASTNodePtr n); 31 | 32 | private: 33 | static void splitExprHelper(vector& bases, 34 | vector& exponents, ASTMulPtr mult); 35 | Environment &env; 36 | Translator translator; 37 | }; 38 | 39 | #endif /*_DESCRIBERELATIONS_H_*/ 40 | -------------------------------------------------------------------------------- /src/ZKP/EqualityProver.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "EqualityProver.h" 3 | #include 4 | #include "MultiExp.h" 5 | 6 | variable_map EqualityProver::computeCommitments(bool indicator) { 7 | 8 | variable_map commitmentValues; 9 | // XXX: do we want to do this for all discrete logs, or just for 10 | // ones that are actually commitments? 11 | for (dlr_map::const_iterator it = env.descriptions.begin(); 12 | it != env.descriptions.end(); ++it) { 13 | DLRepresentation cd = it->second; 14 | ZZ mod = env.groups.at(cd.group)->getModulus(); 15 | 16 | vector bases; 17 | vector baseNames; 18 | vector exps; 19 | for(unsigned j = 0; j < cd.bases.size(); j++) { 20 | // want to add bases and exponents to vectors, then use multi-exp 21 | string baseName = cd.bases[j]->toString(); 22 | string expName = cd.exps[j]->toString(); 23 | 24 | baseNames.push_back(baseName); 25 | bases.push_back(env.variables.at(baseName)); 26 | if(indicator) { 27 | // use exponents from commitment opening 28 | exps.push_back(env.variables.at(expName)); 29 | } 30 | else { 31 | // use exponents from randomized proof opening 32 | exps.push_back(randExps.at(expName)); 33 | } 34 | } 35 | //ZZ result = MultiExp(basesVector, exponentsVector, mod); 36 | ZZ result = env.multiExp(baseNames, bases, exps, mod); 37 | commitmentValues[cd.toString()] = result; 38 | } 39 | return commitmentValues; 40 | } 41 | 42 | variable_map EqualityProver::respond(const ZZ &challenge) { 43 | variable_map response; 44 | for (variable_map::iterator it = randExps.begin(); 45 | it != randExps.end(); ++it) { 46 | ZZ temp = it->second + challenge * env.variables.at(it->first); 47 | response[it->first] = temp; 48 | } 49 | return response; 50 | } 51 | -------------------------------------------------------------------------------- /src/ZKP/EqualityProver.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef _EQUALITYPROVER_H_ 3 | #define _EQUALITYPROVER_H_ 4 | 5 | #include "Environment.h" 6 | #include "../SigmaProver.h" 7 | 8 | class EqualityProver : public SigmaProver { 9 | 10 | public: 11 | /*! the constructor takes in an environment for proving, as well 12 | * as the map r containing randomized exponents */ 13 | EqualityProver(Environment &e, variable_map &r) 14 | : env(e), randExps(r) {} 15 | 16 | EqualityProver(const EqualityProver &o) 17 | : env(o.env), randExps(o.randExps) {} 18 | 19 | ~EqualityProver() {} 20 | 21 | variable_map getCommitments() { return computeCommitments(1); } 22 | 23 | variable_map randomizedProofs() { return computeCommitments(0); } 24 | 25 | variable_map respond(const ZZ &challenge); 26 | 27 | void sanityCheck(); 28 | 29 | private: 30 | variable_map computeCommitments(bool indicator); 31 | 32 | const Environment &env; 33 | variable_map randExps; 34 | }; 35 | 36 | #endif /*_EQUALITYPROVER_H_*/ 37 | -------------------------------------------------------------------------------- /src/ZKP/EqualityVerifier.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "EqualityVerifier.h" 3 | #include "ASTNode.h" 4 | #include 5 | #include "MultiExp.h" 6 | 7 | #define DEBUG 0 8 | 9 | bool EqualityVerifier::canGenerateNewChallenge() const { 10 | // XXX for now, let's leave this class to experienced users and 11 | // have no checks 12 | return true; 13 | } 14 | 15 | bool EqualityVerifier::verify(variable_map &response) { 16 | 17 | for (dlr_map::const_iterator it = env.descriptions.begin(); 18 | it != env.descriptions.end(); ++it) { 19 | DLRepresentation cd = it->second; 20 | // Check if rProof_i * C_i ^ c = SUM(i = 0:n) base_i ^ response_i % mod 21 | ZZ mod = env.groups.at(cd.group)->getModulus(); 22 | ZZ rProofBase = getRandomizedProofs().at(cd.toString()); 23 | 24 | ZZ commitmentBase = env.variables.at(cd.left->toString()); 25 | ZZ rCom = PowerMod(commitmentBase, challenge, mod); 26 | ZZ leftSide = MulMod(rProofBase, rCom, mod); 27 | 28 | vector baseNames; 29 | vector bases; 30 | vector exps; 31 | for(unsigned j = 0; j < cd.bases.size(); j++) { 32 | string baseName = cd.bases[j]->toString(); 33 | baseNames.push_back(baseName); 34 | bases.push_back(env.variables.at(baseName)); 35 | exps.push_back(response.at(cd.exps[j]->toString())); 36 | } 37 | ZZ rightSide = env.multiExp(baseNames, bases, exps, mod); 38 | //ZZ rightSide = MultiExp(bases, exps, mod); 39 | if(leftSide != rightSide) { 40 | cout << "******************************************" << endl; 41 | cout << "failed to verify: " << endl << cd.toString() << endl; 42 | cout << leftSide << endl << " != " << endl << rightSide << endl; 43 | cout << "randomized proof is " << rProofBase << endl; 44 | cout << "commitment is " << commitmentBase << endl; 45 | cout << "******************************************" << endl; 46 | return false; 47 | } 48 | else { 49 | #if DEBUG 50 | cout << "VERIFIED commitment " << cd.toString() << endl; 51 | #endif 52 | } 53 | 54 | } 55 | // if we got here, all equations were verified! 56 | return true; 57 | } 58 | -------------------------------------------------------------------------------- /src/ZKP/EqualityVerifier.h: -------------------------------------------------------------------------------- 1 | #ifndef _EQUALITYVERIFIER_H_ 2 | #define _EQUALITYVERIFIER_H_ 3 | 4 | #include "../SigmaVerifier.h" 5 | #include "Environment.h" 6 | 7 | class EqualityVerifier : public SigmaVerifier { 8 | public: 9 | EqualityVerifier(const variable_map &rProofsArg, Environment &e, 10 | int stat) 11 | : SigmaVerifier(rProofsArg, stat), env(e) {} 12 | 13 | /*! copy constructor */ 14 | EqualityVerifier(const EqualityVerifier &o) 15 | : SigmaVerifier(o), env(o.env) {} 16 | 17 | /*! destructor */ 18 | virtual ~EqualityVerifier() {} 19 | 20 | /*! returns true iff the verifier has the appropriate 21 | * commitments, group definitions, and randomized proofs */ 22 | virtual bool canGenerateNewChallenge() const; 23 | 24 | /*! uses stored randomized proof and response */ 25 | virtual bool verify(variable_map &response); 26 | 27 | /*! used only if canGenerateNewChallenge is true */ 28 | virtual void setChallenge(const ZZ &c) { challenge = c; } 29 | 30 | private: 31 | const Environment &env; 32 | }; 33 | 34 | #endif 35 | -------------------------------------------------------------------------------- /src/ZKP/ExponentSub.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "ExponentSub.h" 3 | #include "Environment.h" 4 | 5 | void ExponentSub::apply(ASTNodePtr n) { 6 | n->visit(*this); 7 | } 8 | 9 | void ExponentSub::applyASTMul(ASTMulPtr mul) { 10 | ASTExprPtr lhs = mul->getLHS(); 11 | ASTExprPtr rhs = mul->getRHS(); 12 | // only if the sides are exprIDs or exprInts do we want to add 1 13 | if (dynamic_pointer_cast(lhs) != 0 || 14 | dynamic_pointer_cast(lhs) != 0) { 15 | ASTPowPtr newLHS = new_ptr(lhs, new_ptr("1")); 16 | lhs = newLHS; 17 | } 18 | if (dynamic_pointer_cast(rhs) != 0 || 19 | dynamic_pointer_cast(rhs) != 0) { 20 | ASTPowPtr newRHS = new_ptr(rhs, new_ptr("1")); 21 | rhs = newRHS; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/ZKP/ExponentSub.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef _EXPONENTSUB_H_ 3 | #define _EXPONENTSUB_H_ 4 | 5 | #include "ASTNode.h" 6 | #include "ASTTVisitor.h" 7 | 8 | class ExponentSub : public ASTTVisitor { 9 | 10 | public: 11 | ExponentSub(Environment &e) : env(e) {} 12 | 13 | void applyASTMul(ASTMulPtr n); 14 | void apply(ASTNodePtr n); 15 | 16 | private: 17 | Environment &env; 18 | }; 19 | 20 | #endif /*_EXPONENTSUB_H_*/ 21 | -------------------------------------------------------------------------------- /src/ZKP/ForExpander.h: -------------------------------------------------------------------------------- 1 | #ifndef __FOREXPANDER_H__ 2 | #define __FOREXPANDER_H__ 3 | 4 | #include "ASTNode.h" 5 | #include "ASTTVisitor.h" 6 | #include 7 | 8 | /*! Applies & expands a tree-parsing "syntactic sugar" for() rule on 9 | * ASTExprs, replacing ASTFor nodes with subtrees of expanded ASTExprs 10 | * joined by the appropriate operator (either ASTMul or ASTAdd). 11 | * 12 | * If variables are used in the upper/lower bound arguments of for(), they 13 | * must be set in the environment before ForExpander is called on the tree. 14 | * 15 | * Supports nesting, e.g.: 16 | * for(i, 1:5, *, for(j, 1:j, +, g_i^x_j)) 17 | * for(i, 1:5, *, g_i^x_i * for(j, 1:j, +, h_j^y_j)) 18 | * 19 | * This class mutates the tree, so that ASTFor doesn't have to 20 | * implement its own getExprType() and eval() logic. Should be run 21 | * after the grammar, before the visitors. 22 | */ 23 | 24 | class ForExpander : public ASTTVisitor { 25 | public: 26 | ForExpander(Environment &env) : e(env) {} 27 | 28 | /*! look up lower and upper bounds of [LB:UB] */ 29 | int lookupBound(ASTExprPtr bnode); 30 | 31 | /*! returns a subtree of expanded ASTExprs, 32 | * joined with ASTMul/ASTAdd nodes */ 33 | ASTExprPtr replaceFor(ASTForExprPtr forNode); 34 | 35 | /*! if this is an ASTFor node, then replace with a subtree of 36 | * expanded ASTExprsPtr */ 37 | void applyASTNode(ASTNodePtr n); 38 | 39 | /*! replace x_i with value of i if this IdentifierSub is inside a 40 | * for context */ 41 | void applyASTIdentifierSub(ASTIdentifierSubPtr n); 42 | 43 | void applyASTListRelation(ASTListRelationPtr n); 44 | 45 | void applyASTDeclIdentifierSub(ASTDeclIdentifierSubPtr n); 46 | 47 | vector replaceFor(ASTForRelPtr forNode); 48 | 49 | private: 50 | Environment& e; 51 | boost::unordered_map indexToCur; 52 | stack parent; // track the parent of each ASTNode 53 | }; 54 | 55 | #endif 56 | -------------------------------------------------------------------------------- /src/ZKP/Interpreter.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef _INTERPRETER_H_ 3 | #define _INTERPRETER_H_ 4 | 5 | #include "Environment.h" 6 | #include "ASTNode.h" 7 | #include "../SigmaProof.h" 8 | 9 | /*! 10 | * \brief This class will interpret instructions given by a program 11 | */ 12 | 13 | typedef pair cache_key_pair; 14 | 15 | class Interpreter { 16 | 17 | public: 18 | Interpreter() {} 19 | 20 | Interpreter(const Interpreter &o) : env(o.env), tree(o.tree) {} 21 | 22 | /*! to load from the cache */ 23 | Interpreter(pair &p) 24 | : env(p.second), tree(p.first) {} 25 | 26 | virtual ~Interpreter() {} 27 | 28 | /*! this will run all the visitors that are meant to be used 29 | * BEFORE user has given any numeric values (maybe groups though) */ 30 | void check(const string &programName, input_map inputs, group_map grps); 31 | void check(const string &programName) 32 | { check(programName, input_map(), group_map()); } 33 | void check(const string &programName, input_map &inputs) 34 | { check(programName, inputs, group_map()); } 35 | void check(const string &programName, group_map &groups) 36 | { check(programName, input_map(), groups); } 37 | 38 | Environment getEnvironment() { return env; } 39 | 40 | protected: 41 | void cachePowers(); 42 | 43 | cache_key_pair hashForCache(const string &fname, input_map i, group_map g); 44 | 45 | /*! used by the prover/verifier to compute any runtime values 46 | * that are needed for the proof but haven't been handed in 47 | * by the user (so this will only be run AFTER the user has given 48 | * in numeric values */ 49 | virtual void computeIntermediateValues() = 0; 50 | 51 | Environment env; 52 | ASTNodePtr tree; 53 | }; 54 | 55 | #endif /*_INTERPRETER_H_*/ 56 | -------------------------------------------------------------------------------- /src/ZKP/InterpreterCache.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef _INTERPRETERCACHE_H_ 3 | #define _INTERPRETERCACHE_H_ 4 | 5 | #include "ASTNode.h" 6 | #include "Environment.h" 7 | #include "Interpreter.h" 8 | 9 | /*! 10 | * \brief A storage container that keeps previously "compiled" code 11 | * (AST & Environment) for the interpreter to load up again as it wants 12 | */ 13 | 14 | struct CacheValue { 15 | 16 | CacheValue() {} 17 | 18 | CacheValue(ASTNodePtr n, const Environment& e) 19 | : tree(n), env(e) {} 20 | 21 | ASTNodePtr tree; 22 | Environment env; 23 | }; 24 | 25 | class InterpreterCache { 26 | 27 | public: 28 | static InterpreterCache& instance() { 29 | // local static object initialization 30 | static InterpreterCache _icache; 31 | return _icache; 32 | } 33 | 34 | typedef boost::unordered_map cache_t; 35 | 36 | // store values in the cache 37 | static void store(cache_key_pair key, ASTNodePtr n, 38 | Environment &env) { 39 | instance().cache[key] = CacheValue(n, env); 40 | } 41 | 42 | static bool contains(cache_key_pair key) { 43 | return instance().cache.count(key) != 0; 44 | } 45 | 46 | static CacheValue& get(cache_key_pair key) { 47 | return instance().cache.at(key); 48 | } 49 | 50 | private: 51 | cache_t cache; 52 | 53 | InterpreterCache() {} // constructor (ctor) is hidden 54 | InterpreterCache( InterpreterCache const & ); // copy ctor is hidden 55 | // assignment operator is hidden 56 | InterpreterCache& operator=( InterpreterCache const & ); 57 | ~InterpreterCache() {} // destructor (dtor) is hidden 58 | }; 59 | 60 | #endif /*_INTERPRETERCACHE_H_*/ 61 | -------------------------------------------------------------------------------- /src/ZKP/InterpreterProver.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef _INTERPRETERPROVER_H_ 3 | #define _INTERPRETERPROVER_H_ 4 | 5 | #include "Interpreter.h" 6 | #include "../SigmaProof.h" 7 | 8 | class InterpreterProver : public Interpreter { 9 | 10 | public: 11 | InterpreterProver() {} 12 | 13 | InterpreterProver(const InterpreterProver &o) 14 | : Interpreter(o) {} 15 | 16 | /*! this constructor should be used for programs that are 17 | * pre-compiled */ 18 | InterpreterProver(pair &p) 19 | : Interpreter(p) {} 20 | 21 | /*! this will run all the visitors that need to be run 22 | * AFTER we have actual values */ 23 | void compute(variable_map &v, group_map g = group_map()); 24 | 25 | /*! returns all public variables (includes bases as well as 26 | * commitments) */ 27 | variable_map getPublicVariables(); 28 | 29 | /*! to be called after running check and compute: returns a 30 | * proof of the validity of the program given to check */ 31 | SigmaProof computeProof(const hashalg_t &hashAlg); 32 | 33 | private: 34 | /*! this decomposes key values in decomposition maps into their 35 | * four squares representation, then assigns values appropriately */ 36 | void decompose(); 37 | 38 | /*! this forms random exponents for the variables in randoms */ 39 | void formRandomExponents(); 40 | 41 | /*! this computes all values in the expressions and comsToCompute 42 | * maps in the environment */ 43 | void computeIntermediateValues(); 44 | 45 | /*! for each exponent, creates a random exponent to be used by 46 | * equality prover */ 47 | variable_map makeRandomizedExponents(); 48 | 49 | friend class boost::serialization::access; 50 | template 51 | void serialize(Archive& ar, const unsigned int ver) { 52 | ar & base_object_nvp(Interpreter); 53 | } 54 | 55 | }; 56 | 57 | #endif /*_INTERPRETERPROVER_H_*/ 58 | -------------------------------------------------------------------------------- /src/ZKP/InterpreterVerifier.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "InterpreterVerifier.h" 3 | #include "EqualityVerifier.h" 4 | #include "BindGroupValues.h" 5 | 6 | void InterpreterVerifier::compute(variable_map &v, const variable_map &p, 7 | const variable_map &p2, group_map g) { 8 | // store all information in the environment 9 | if (!g.empty()) { 10 | env.groups = g; 11 | env.variables = v; 12 | env.groups[Environment::NO_GROUP] = 0; 13 | // run BindGroupValues 14 | BindGroupValues binder(env); 15 | binder.apply(tree); 16 | } 17 | // XXX: again, is there a more efficient way? 18 | for (variable_map::iterator it = v.begin(); it != v.end(); ++it) { 19 | env.variables[it->first] = it->second; 20 | } 21 | for (variable_map::const_iterator it = p.begin(); it != p.end(); ++it) { 22 | // want to store prover's commitments and public bases, but any 23 | // inputs given to the verifier take precedence 24 | if (env.variables.count(it->first) == 0) { 25 | env.variables[it->first] = it->second; 26 | } 27 | } 28 | // do same thing for optional additional inputs 29 | for (variable_map::const_iterator it = p2.begin(); it != p2.end(); ++it) { 30 | if (env.variables.count(it->first) == 0) { 31 | env.variables[it->first] = it->second; 32 | } 33 | } 34 | // now we just need to deal with commitments for any range proofs 35 | // (note: this needs to be run after we get values from prover) 36 | computeIntermediateValues(); 37 | } 38 | 39 | bool InterpreterVerifier::verify(const SigmaProof &proof, int stat) { 40 | // if some commitments were already wrong, no point in continuing 41 | if (badComs) 42 | return false; 43 | else { 44 | EqualityVerifier eq(proof.getRandomizedProofs(), env, stat); 45 | eq.setChallenge(proof.computeChallenge()); 46 | variable_map res = proof.getResponses(); 47 | return eq.verify(res); 48 | } 49 | } 50 | 51 | void InterpreterVerifier::computeIntermediateValues() { 52 | // form range commitments 53 | for (dlr_map::iterator it = env.rangeComs.begin(); 54 | it != env.rangeComs.end(); ++it) { 55 | env.variables[it->first] = it->second.computeValue(env); 56 | } 57 | // for any decompositions, want to check that c_x = product over c_xi2, so 58 | // that x = x_1^2 + x_2^2 + x_3^2 + x_4^2 59 | badComs = false; 60 | for (decomp_map::iterator it = env.decompositions.begin(); 61 | it != env.decompositions.end(); ++it) { 62 | ZZ squareProd = to_ZZ(1); 63 | vector fourNames = it->second; 64 | ZZ mod = env.getGroup(fourNames[0].decompSquare)->getModulus(); 65 | for (int i = 0; i < 4; i++) { 66 | string name = fourNames[i].decompSquare; 67 | squareProd = MulMod(squareProd, env.getCommitmentValue(name), mod); 68 | } 69 | // if this product isn't equal to the original c_x, immediately know 70 | // proof won't be correct because commitments are formed improperly 71 | if (squareProd != env.getCommitmentValue(it->first)) { 72 | cout << "Product of square commitments not equal to original " 73 | "commitment: " << endl; 74 | cout << squareProd << " != " << env.getCommitmentValue(it->first) 75 | << endl; 76 | badComs = true; 77 | } 78 | } 79 | env.rangeComs.clear(); 80 | env.decompositions.clear(); 81 | } 82 | -------------------------------------------------------------------------------- /src/ZKP/InterpreterVerifier.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef _INTERPRETERVERIFIER_H_ 3 | #define _INTERPRETERVERIFIER_H_ 4 | 5 | #include "Interpreter.h" 6 | #include "../SigmaProof.h" 7 | 8 | class InterpreterVerifier : public Interpreter { 9 | 10 | public: 11 | InterpreterVerifier() {} 12 | 13 | InterpreterVerifier(const InterpreterVerifier &o) 14 | : Interpreter(o) {} 15 | 16 | InterpreterVerifier(pair &p) 17 | : Interpreter(p) {} 18 | 19 | /*! takes in groups and variables; first merges its own 20 | * variables with input from the prover and then creates 21 | * the proper environment */ 22 | void compute(variable_map &v, const variable_map &p, 23 | const variable_map &p2, group_map g); 24 | void compute(variable_map &v, const variable_map &p) 25 | { compute(v, p, variable_map(), group_map()); } 26 | void compute(variable_map &v, const variable_map &p, group_map g) 27 | { compute(v, p, variable_map(), g); } 28 | void compute(variable_map &v, const variable_map &p, 29 | const variable_map &p2) { compute(v, p, p2, group_map()); } 30 | 31 | /*! given a proof, calls on the equality verifier to check if 32 | * the proof is valid or not */ 33 | bool verify(const SigmaProof &proof, int stat); 34 | 35 | private: 36 | /*! this computes all the commitment values in the rangeComs map */ 37 | void computeIntermediateValues(); 38 | 39 | // indicates if commitments were formed correctly (for non-negative) 40 | bool badComs; 41 | }; 42 | 43 | 44 | #endif /*_INTERPRETERVERIFIER_H_*/ 45 | -------------------------------------------------------------------------------- /src/ZKP/PowerCache.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef _POWERCACHE_H_ 3 | #define _POWERCACHE_H_ 4 | 5 | #include 6 | #include 7 | #include 8 | 9 | class PowerCache { 10 | public: 11 | struct Table { 12 | Table() {} 13 | int k, bits, numLookups; 14 | ZZ mod; 15 | vector > table; 16 | }; 17 | typedef boost::unordered_map cache_t; 18 | 19 | PowerCache() {} 20 | PowerCache(const PowerCache &o) : cache(o.cache) {} 21 | ~PowerCache() {} 22 | 23 | void store(const string &baseName, const ZZ &base, const ZZ &mod, 24 | int bits, int k) { 25 | Table table; 26 | int lookupSize = 1 << k; 27 | table.numLookups = bits / k + 1; 28 | table.k = k; 29 | table.bits = bits; 30 | table.mod = mod; 31 | ZZ multiplier = base; 32 | vector > tab; 33 | for (int i = 0; i < table.numLookups; i++) { 34 | vector lookup(lookupSize); 35 | lookup[0] = 1; 36 | for (int j = 1; j < lookupSize; j++) { 37 | // do square-and-multiply (sort of) 38 | lookup[j] = MulMod(multiplier, lookup[j-1], mod); 39 | } 40 | multiplier = MulMod(multiplier, lookup[lookupSize - 1], mod); 41 | tab.push_back(lookup); 42 | } 43 | table.table = tab; 44 | cache[baseName] = table; 45 | } 46 | 47 | ZZ modPow(const Table &table, const ZZ& n) const { 48 | int word; /* the word to look up. 0 0) { 63 | MulMod(result, result, table.table[row][word], table.mod); 64 | } 65 | } 66 | return result; 67 | } 68 | 69 | void modPow(ZZ& res, const string& baseName, const ZZ& n, 70 | const ZZ& mod) const { 71 | // look up table 72 | const Table &table = cache.at(baseName); 73 | assert(mod == table.mod); 74 | res = modPow(table, n); 75 | } 76 | 77 | ZZ modPow(const string& baseName, const ZZ& n, const ZZ& mod) const { 78 | ZZ r = 0; modPow(r, baseName, n, mod); return r; 79 | } 80 | 81 | bool contains(const string &baseName) const 82 | {return cache.count(baseName) != 0;} 83 | 84 | void clear() { cache.clear(); } 85 | 86 | private: 87 | cache_t cache; 88 | }; 89 | 90 | #endif /*_POWERCACHE_H_*/ 91 | -------------------------------------------------------------------------------- /src/ZKP/Translator.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef _TRANSLATOR_H_ 3 | #define _TRANSLATOR_H_ 4 | 5 | #include "Environment.h" 6 | #include "ASTNode.h" 7 | 8 | class Translator { 9 | 10 | public: 11 | Translator(Environment &e) : env(e), counter(0) {} 12 | virtual ~Translator() {} 13 | 14 | /*! add the description to output list */ 15 | void describeDLR(DLRepresentation &c); 16 | 17 | /*! reduce commitments to form needed to prove x = a * b */ 18 | void describeMultiplication(DLRepresentation &product, 19 | DLRepresentation &factor1, 20 | DLRepresentation &factor2); 21 | 22 | /*! reduce commitments to form needed to prove y = x^2 */ 23 | void describeSquare(DLRepresentation &product, DLRepresentation &factor); 24 | 25 | void describeNonNegative(DLRepresentation &c); 26 | 27 | /*! for proving low <= val < high using the specified group */ 28 | void describeRange(ASTExprPtr val, ASTIdentifierLitPtr group, 29 | ASTExprPtr low, ASTExprPtr high); 30 | 31 | dlr_map getDescriptions() { return output; } 32 | 33 | protected: 34 | /*! helper for creating new nodes in the ASTPtr */ 35 | ASTExprIdentifierPtr nameNode(const string &name); 36 | 37 | Environment &env; 38 | dlr_map output; 39 | int counter; 40 | 41 | }; 42 | 43 | #endif /*_TRANSLATOR_H_*/ 44 | 45 | 46 | -------------------------------------------------------------------------------- /src/ZKP/TypeChecker.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "TypeChecker.h" 3 | #include "Environment.h" 4 | 5 | void TypeChecker::applyASTDeclRandExponents(ASTDeclRandExponentsPtr n) { 6 | 7 | ASTListDeclPtr exps = n->getExponents(); 8 | string grpname = n->getGroup()->getName(); 9 | 10 | ASTDeclIdentifierSubPtr exp; 11 | ASTDeclIDRangePtr expRange; 12 | VarInfo info(grpname, VarInfo::EXPONENT); 13 | for (int i = 0; i < exps->size(); i++) { 14 | ASTNodePtr ith = exps->get(i); 15 | if ((exp = dynamic_pointer_cast(ith)) != 0){ 16 | // associate exponent with its group 17 | env.varTypes[exp->getName()] = info; 18 | } else if((expRange=dynamic_pointer_cast(ith))!=0){ 19 | for(int j = expRange->getLBound(); j <= expRange->getUBound(); j++){ 20 | env.varTypes[expRange->getName(j)] = info; 21 | } 22 | } else { 23 | throw CashException(CashException::CE_PARSE_ERROR, 24 | "Variable %d in list was not a valid exponent name", i); 25 | } 26 | } 27 | } 28 | 29 | void TypeChecker::applyASTDeclEqual(ASTDeclEqualPtr n) { 30 | 31 | ASTDeclIdentifierSubPtr lhs = n->getId(); 32 | ASTExprPtr rhs = n->getExpr(); 33 | // recursively work to find expression type and assign it to the 34 | // left-hand side 35 | // if any errors are found (for example, trying to raise an exponent to 36 | // an element) an exception will be thrown 37 | env.varTypes[lhs->getName()] = rhs->getExprType(env); 38 | } 39 | 40 | void TypeChecker::applyASTEqual(ASTEqualPtr n) { 41 | // same as with the decl equal 42 | ASTIdentifierSubPtr lhs = n->getId(); 43 | ASTExprPtr rhs = n->getExpr(); 44 | env.varTypes[lhs->getName()] = rhs->getExprType(env); 45 | } 46 | 47 | void TypeChecker::apply(ASTNodePtr n) { 48 | n->visit(*this); 49 | } 50 | -------------------------------------------------------------------------------- /src/ZKP/TypeChecker.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef _TYPECHECKER_H_ 3 | #define _TYPECHECKER_H_ 4 | 5 | #include "ASTNode.h" 6 | #include "ASTTVisitor.h" 7 | 8 | class TypeChecker : public ASTTVisitor { 9 | 10 | public: 11 | /*! run before we have actual values (and after GroupIdentifier) */ 12 | TypeChecker(Environment &e) : env(e) {} 13 | 14 | /*! associate these as exponents in the given group */ 15 | void applyASTDeclRandExponents(ASTDeclRandExponentsPtr n); 16 | 17 | /*! check to make sure RHS is valid; if it is, associate left-hand side 18 | * with appropriate group and type 19 | */ 20 | void applyASTDeclEqual(ASTDeclEqualPtr n); 21 | 22 | /*! check validity of RHS and assign LHS to correct group/type */ 23 | void applyASTEqual(ASTEqualPtr n); 24 | 25 | /*! check the whole tree */ 26 | void apply(ASTNodePtr n); 27 | 28 | private: 29 | Environment &env; 30 | 31 | }; 32 | 33 | #endif /*_TYPECHECKER_H_*/ 34 | -------------------------------------------------------------------------------- /src/ZKP/TypeIdentifier.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef _TYPEIDENTIFIER_H_ 3 | #define _TYPEIDENTIFIER_H_ 4 | 5 | #include "ASTTVisitor.h" 6 | #include "ASTNode.h" 7 | 8 | /*! 9 | * \brief This class is used to identify the group in which a given 10 | * variable is contained and also the privacy setting for that variable 11 | */ 12 | 13 | class TypeIdentifier : public ASTTVisitor { 14 | 15 | public: 16 | /*! this visitor should be used before we have actual values */ 17 | TypeIdentifier(Environment &e) : env(e) {} 18 | 19 | /*! used for privacy settings */ 20 | void applyASTProof(ASTProofPtr n); 21 | 22 | /*! used to associate elements/exponents/generators with their groups */ 23 | void applyASTDeclElements(ASTDeclElementsPtr n); 24 | void applyASTDeclExponents(ASTDeclExponentsPtr n); 25 | void applyASTDeclGroup(ASTDeclGroupPtr n); 26 | 27 | /*! used to associate integers with no group */ 28 | void applyASTDeclIntegers(ASTDeclIntegersPtr n); 29 | void applyASTRandomBnd(ASTRandomBndPtr n); 30 | void applyASTRandomPrime(ASTRandomPrimePtr n); 31 | 32 | /*! associate all variables with groups and privacy setting */ 33 | void apply(ASTNodePtr n); 34 | 35 | private: 36 | Environment &env; 37 | bool isPrivate; 38 | }; 39 | 40 | #endif /*_GROUPIDENTIFIER_H_*/ 41 | 42 | -------------------------------------------------------------------------------- /src/ZKP/UndefinedVariables.cpp: -------------------------------------------------------------------------------- 1 | #include "UndefinedVariables.h" 2 | 3 | void UndefinedVariables::apply(ASTNodePtr n){ 4 | // need to do two passes over the tree because things can be declared 5 | // in 'prove knowledge of' block and used in 'given' block and vice 6 | // versa 7 | n->visit(*this); 8 | n->visit(*this); 9 | for (def_map::iterator it = definedVars.begin(); 10 | it != definedVars.end(); ++it) { 11 | if (!it->second) 12 | throw CashException(CashException::CE_PARSE_ERROR, 13 | "%s has not been defined", it->first.c_str()); 14 | } 15 | } 16 | 17 | void UndefinedVariables::applyASTDeclIdentifierLit(ASTDeclIdentifierLitPtr n){ 18 | definedVars[n->getName()] = true; 19 | } 20 | 21 | void UndefinedVariables::applyASTDeclIdentifierSub(ASTDeclIdentifierSubPtr n){ 22 | definedVars[n->getName()] = true; 23 | } 24 | 25 | void UndefinedVariables::applyASTDeclIDRange(ASTDeclIDRangePtr n){ 26 | for(int i = n->getLBound(); i <= n->getUBound(); i++){ 27 | definedVars[n->getName(i)] = true; 28 | } 29 | } 30 | 31 | void UndefinedVariables::applyASTIdentifierLit(ASTIdentifierLitPtr n){ 32 | definedVars[n->getName()] = (definedVars.count(n->getName()) != 0); 33 | } 34 | 35 | void UndefinedVariables::applyASTIdentifierSub(ASTIdentifierSubPtr n){ 36 | definedVars[n->getName()] = (definedVars.count(n->getName()) != 0); 37 | } 38 | -------------------------------------------------------------------------------- /src/ZKP/UndefinedVariables.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef _UNDEFINEDVARIABLES_H_ 3 | #define _UNDEFINEDVARIABLES_H_ 4 | 5 | #include "ASTTVisitor.h" 6 | #include "ASTNode.h" 7 | #include 8 | 9 | /*! 10 | * \brief This class is used to see if any variables are used without first 11 | * being defined 12 | */ 13 | 14 | using std::string; 15 | typedef boost::unordered_map def_map; 16 | 17 | class UndefinedVariables : public ASTTVisitor { 18 | 19 | public: 20 | 21 | /*! this visitor is used before we have actual values */ 22 | UndefinedVariables() {} 23 | 24 | /*! finds all variables, if no exception is thrown then all 25 | * used variables have been defined! */ 26 | void apply(ASTNodePtr n); 27 | 28 | /*! once a variable is declared, put it in the map */ 29 | void applyASTDeclIdentifierLit(ASTDeclIdentifierLitPtr n); 30 | void applyASTDeclIdentifierSub(ASTDeclIdentifierSubPtr n); 31 | void applyASTDeclIDRange(ASTDeclIDRangePtr n); 32 | 33 | /*! once a variable is used, check to see that it has been defined; 34 | * if not throw an exception */ 35 | void applyASTIdentifierLit(ASTIdentifierLitPtr n); 36 | void applyASTIdentifierSub(ASTIdentifierSubPtr n); 37 | 38 | private: 39 | def_map definedVars; 40 | }; 41 | 42 | #endif /*_UNDEFINEDVARIABLES_H_*/ 43 | -------------------------------------------------------------------------------- /src/ZKP/UnusedVariables.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "UnusedVariables.h" 3 | 4 | void UnusedVariables::applyASTDeclIdentifierLit(ASTDeclIdentifierLitPtr n){ 5 | definedVars[n->getName()] = false; 6 | } 7 | 8 | void UnusedVariables::applyASTDeclIdentifierSub(ASTDeclIdentifierSubPtr n){ 9 | definedVars[n->getName()] = false; 10 | } 11 | 12 | void UnusedVariables::applyASTDeclIDRange(ASTDeclIDRangePtr n){ 13 | for(int i = n->getLBound(); i <= n->getUBound(); i++){ 14 | definedVars[n->getName(i)] = false; 15 | } 16 | } 17 | 18 | void UnusedVariables::applyASTIdentifierLit(ASTIdentifierLitPtr n){ 19 | definedVars[n->getName()] = true; 20 | } 21 | 22 | void UnusedVariables::applyASTIdentifierSub(ASTIdentifierSubPtr n){ 23 | definedVars[n->getName()] = true; 24 | } 25 | 26 | void UnusedVariables::apply(ASTNodePtr n) { 27 | // need to do two passes over tree 28 | n->visit(*this); 29 | n->visit(*this); 30 | for (def_variable_map::iterator it = definedVars.begin(); 31 | it != definedVars.end(); ++it) { 32 | if (!it->second) 33 | cout << "Warning: variable " << it->first << " is never used" << endl; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/ZKP/UnusedVariables.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef _UNUSEDVARIABLES_H_ 3 | #define _UNUSEDVARIABLES_H_ 4 | 5 | #include "ASTTVisitor.h" 6 | #include "ASTNode.h" 7 | #include 8 | 9 | /*! 10 | * \brief This class will warn the user if a variable is declared but never 11 | * used 12 | */ 13 | 14 | typedef boost::unordered_map def_variable_map; 15 | 16 | class UnusedVariables : public ASTTVisitor { 17 | 18 | public: 19 | /*! this visitor is used before we have actual values */ 20 | UnusedVariables() {} 21 | 22 | /*! when node is declared, put it in the map (as unused) */ 23 | void applyASTDeclIdentifierLit(ASTDeclIdentifierLitPtr n); 24 | void applyASTDeclIdentifierSub(ASTDeclIdentifierSubPtr n); 25 | void applyASTDeclIDRange(ASTDeclIDRangePtr n); 26 | 27 | /*! once a variable is used, change its entry in the map to true; 28 | * because we run this after UndefinedVariables can assume all 29 | * variables that are being used have been defined */ 30 | void applyASTIdentifierLit(ASTIdentifierLitPtr n); 31 | void applyASTIdentifierSub(ASTIdentifierSubPtr n); 32 | 33 | /*! will go through all variable declarations/usages and warn the 34 | * user if a variable is being defined but not used */ 35 | void apply(ASTNodePtr n); 36 | 37 | private: 38 | def_variable_map definedVars; 39 | 40 | }; 41 | 42 | #endif /*_UNUSEDVARIABLES_H_*/ 43 | -------------------------------------------------------------------------------- /src/ZKP/ZKPLexer.hpp: -------------------------------------------------------------------------------- 1 | #ifndef INC_ZKPLexer_hpp_ 2 | #define INC_ZKPLexer_hpp_ 3 | 4 | #include 5 | /* $ANTLR 2.7.7 (20090708): "zkp.g" -> "ZKPLexer.hpp"$ */ 6 | #include 7 | #include 8 | #include 9 | #include "ZKPParserTokenTypes.hpp" 10 | #include 11 | #line 3 "zkp.g" 12 | 13 | //#include "../NTL/ZZ.h" 14 | //namespace="brownie" XXX use namespaces someday 15 | #include "ASTNode.h" 16 | #include "new_ptr.hpp" 17 | 18 | #line 19 "ZKPLexer.hpp" 19 | class CUSTOM_API ZKPLexer : public ANTLR_USE_NAMESPACE(antlr)CharScanner, public ZKPParserTokenTypes 20 | { 21 | #line 1 "zkp.g" 22 | #line 23 "ZKPLexer.hpp" 23 | private: 24 | void initLiterals(); 25 | public: 26 | bool getCaseSensitiveLiterals() const 27 | { 28 | return true; 29 | } 30 | public: 31 | ZKPLexer(ANTLR_USE_NAMESPACE(std)istream& in); 32 | ZKPLexer(ANTLR_USE_NAMESPACE(antlr)InputBuffer& ib); 33 | ZKPLexer(const ANTLR_USE_NAMESPACE(antlr)LexerSharedInputState& state); 34 | ANTLR_USE_NAMESPACE(antlr)RefToken nextToken(); 35 | public: void mLPAREN(bool _createToken); 36 | public: void mRPAREN(bool _createToken); 37 | public: void mLBRACKET(bool _createToken); 38 | public: void mRBRACKET(bool _createToken); 39 | public: void mLCURLY(bool _createToken); 40 | public: void mRCURLY(bool _createToken); 41 | public: void mCOMMA(bool _createToken); 42 | public: void mSCOLON(bool _createToken); 43 | public: void mCOLON(bool _createToken); 44 | public: void mCEQUAL(bool _createToken); 45 | public: void mEQUAL(bool _createToken); 46 | public: void mLTHAN(bool _createToken); 47 | public: void mGTHAN(bool _createToken); 48 | public: void mLEQ(bool _createToken); 49 | public: void mGEQ(bool _createToken); 50 | public: void mADD(bool _createToken); 51 | public: void mSUB(bool _createToken); 52 | public: void mMUL(bool _createToken); 53 | public: void mDIV(bool _createToken); 54 | public: void mPOW(bool _createToken); 55 | public: void mAMP(bool _createToken); 56 | public: void mSUBSCRIPT(bool _createToken); 57 | public: void mID(bool _createToken); 58 | public: void mINTLIT(bool _createToken); 59 | public: void mWS(bool _createToken); 60 | public: void mCMT(bool _createToken); 61 | private: 62 | 63 | static const unsigned long _tokenSet_0_data_[]; 64 | static const ANTLR_USE_NAMESPACE(antlr)BitSet _tokenSet_0; 65 | }; 66 | 67 | #endif /*INC_ZKPLexer_hpp_*/ 68 | -------------------------------------------------------------------------------- /src/ZKP/ZKPParserTokenTypes.hpp: -------------------------------------------------------------------------------- 1 | #ifndef INC_ZKPParserTokenTypes_hpp_ 2 | #define INC_ZKPParserTokenTypes_hpp_ 3 | 4 | /* $ANTLR 2.7.7 (20090708): "zkp.g" -> "ZKPParserTokenTypes.hpp"$ */ 5 | 6 | #ifndef CUSTOM_API 7 | # define CUSTOM_API 8 | #endif 9 | 10 | #ifdef __cplusplus 11 | struct CUSTOM_API ZKPParserTokenTypes { 12 | #endif 13 | enum { 14 | EOF_ = 1, 15 | LITERAL_computation = 4, 16 | COLON = 5, 17 | LITERAL_given = 6, 18 | LITERAL_compute = 7, 19 | LITERAL_proof = 8, 20 | LITERAL_prove = 9, 21 | LITERAL_knowledge = 10, 22 | LITERAL_of = 11, 23 | LITERAL_such = 12, 24 | LITERAL_that = 13, 25 | LITERAL_integer = 14, 26 | LITERAL_integers = 15, 27 | LITERAL_in = 16, 28 | LBRACKET = 17, 29 | COMMA = 18, 30 | RPAREN = 19, 31 | LITERAL_prime = 20, 32 | LITERAL_primes = 21, 33 | LITERAL_length = 22, 34 | LITERAL_random = 23, 35 | LITERAL_group = 24, 36 | EQUAL = 25, 37 | LITERAL_modulus = 26, 38 | LITERAL_exponent = 27, 39 | LITERAL_exponents = 28, 40 | LITERAL_element = 29, 41 | LITERAL_elements = 30, 42 | LITERAL_for = 31, 43 | LPAREN = 32, 44 | LITERAL_commitment = 33, 45 | LITERAL_to = 34, 46 | SUBSCRIPT = 35, 47 | ID = 36, 48 | INTLIT = 37, 49 | CEQUAL = 38, 50 | LITERAL_range = 39, 51 | LTHAN = 40, 52 | LEQ = 41, 53 | GTHAN = 42, 54 | GEQ = 43, 55 | ADD = 44, 56 | SUB = 45, 57 | MUL = 46, 58 | DIV = 47, 59 | POW = 48, 60 | RBRACKET = 49, 61 | LCURLY = 50, 62 | RCURLY = 51, 63 | SCOLON = 52, 64 | AMP = 53, 65 | WS = 54, 66 | CMT = 55, 67 | NULL_TREE_LOOKAHEAD = 3 68 | }; 69 | #ifdef __cplusplus 70 | }; 71 | #endif 72 | #endif /*INC_ZKPParserTokenTypes_hpp_*/ 73 | -------------------------------------------------------------------------------- /src/ZKP/ZKPParserTokenTypes.txt: -------------------------------------------------------------------------------- 1 | // $ANTLR 2.7.7 (20090708): zkp.g -> ZKPParserTokenTypes.txt$ 2 | ZKPParser // output token vocab name 3 | LITERAL_computation="computation"=4 4 | COLON=5 5 | LITERAL_given="given"=6 6 | LITERAL_compute="compute"=7 7 | LITERAL_proof="proof"=8 8 | LITERAL_prove="prove"=9 9 | LITERAL_knowledge="knowledge"=10 10 | LITERAL_of="of"=11 11 | LITERAL_such="such"=12 12 | LITERAL_that="that"=13 13 | LITERAL_integer="integer"=14 14 | LITERAL_integers="integers"=15 15 | LITERAL_in="in"=16 16 | LBRACKET=17 17 | COMMA=18 18 | RPAREN=19 19 | LITERAL_prime="prime"=20 20 | LITERAL_primes="primes"=21 21 | LITERAL_length="length"=22 22 | LITERAL_random="random"=23 23 | LITERAL_group="group"=24 24 | EQUAL=25 25 | LITERAL_modulus="modulus"=26 26 | LITERAL_exponent="exponent"=27 27 | LITERAL_exponents="exponents"=28 28 | LITERAL_element="element"=29 29 | LITERAL_elements="elements"=30 30 | LITERAL_for="for"=31 31 | LPAREN=32 32 | LITERAL_commitment="commitment"=33 33 | LITERAL_to="to"=34 34 | SUBSCRIPT=35 35 | ID=36 36 | INTLIT=37 37 | CEQUAL=38 38 | LITERAL_range="range"=39 39 | LTHAN=40 40 | LEQ=41 41 | GTHAN=42 42 | GEQ=43 43 | ADD=44 44 | SUB=45 45 | MUL=46 46 | DIV=47 47 | POW=48 48 | RBRACKET=49 49 | LCURLY=50 50 | RCURLY=51 51 | SCOLON=52 52 | AMP=53 53 | WS=54 54 | CMT=55 55 | -------------------------------------------------------------------------------- /src/ZKP/examples/allkinds.txt: -------------------------------------------------------------------------------- 1 | 2 | computation: 3 | given: 4 | group: G = 5 | integers: J, W 6 | 7 | compute: 8 | random exponents in G: a, b, r_a, r_b, r_x, r_y, r_J 9 | c_J := g^J * h^r_J 10 | x := a * b 11 | y := x^2 12 | c_a := g^a * h^r_a 13 | c_b := g^b * h^r_b 14 | c_x := g^x * h^r_x 15 | c_y := g^y * h^r_y 16 | dl := g^x * h^a 17 | 18 | proof: 19 | given: 20 | group: G = 21 | elements in G: c_a, c_b, c_x, c_y, W, dl 22 | c_a = g^a * h^r_a 23 | c_b = g^b * h^r_b 24 | c_x = g^x * h^r_x 25 | c_y = g^y * h^r_y 26 | 27 | prove knowledge of: 28 | exponents in G: a, b, x, y 29 | integers: J 30 | 31 | such that: 32 | x = a * b 33 | y = x^2 34 | 0 <= J < W 35 | dl = g^x * h^a 36 | 37 | -------------------------------------------------------------------------------- /src/ZKP/examples/badDLR.txt: -------------------------------------------------------------------------------- 1 | 2 | computation: 3 | given: 4 | group: G = 5 | integers: J 6 | compute: 7 | random exponents in G: r_C, s 8 | alpha := 1 / (s + J) 9 | C := g^s * h^r_C 10 | 11 | proof: 12 | given: 13 | group: G = 14 | elements in G: C 15 | commitment to s: C = g^s * h^r_C 16 | 17 | prove knowledge of: 18 | exponents in G: r_C, alpha, s 19 | integers: J 20 | 21 | such that: 22 | g = (g^J * C)^alpha * h^(-r_C * alpha) 23 | -------------------------------------------------------------------------------- /src/ZKP/examples/badmult.txt: -------------------------------------------------------------------------------- 1 | computation: 2 | given: 3 | group: G = 4 | exponents in G: a, b 5 | compute: 6 | random exponents in G: r_x, r_a, r_b 7 | x := a * b 8 | c_x := g^x * h^r_x 9 | c_a := g^a * h^r_a 10 | c_b := g^b * h^r_b 11 | oops := g^g 12 | 13 | proof: 14 | given: 15 | group: G = 16 | elements in G: c_x, c_a, c_b 17 | commitment to x: c_x = g^x * h^r_x 18 | commitment to a: c_a = g^a * h^r_a 19 | commitment to b: c_b = g^b * h^r_b 20 | 21 | prove knowledge of: 22 | exponents in G: x, a, b, r_x, r_a, r_b 23 | 24 | such that: 25 | x = a * b 26 | -------------------------------------------------------------------------------- /src/ZKP/examples/cl-issue.txt: -------------------------------------------------------------------------------- 1 | // issue a CL blind signature 2 | 3 | computation: 4 | given: 5 | group: pkGroup = 6 | element in pkGroup: C 7 | exponents in pkGroup: x[1:k+l] 8 | integers: stat, modSize, l_x 9 | compute: 10 | random integer in [0,2^(modSize+l_x+stat)): vdoubleprime 11 | random prime of length l_x+2: e 12 | einverse := 1/e 13 | A := (f * C * h^vdoubleprime * for(i, l+1:k+l, *, g_i^x_i))^einverse 14 | 15 | proof: 16 | given: 17 | group: pkGroup = 18 | elements in pkGroup: A, C 19 | exponents in pkGroup: e, vdoubleprime, x[l+1:k] 20 | 21 | prove knowledge of: 22 | exponents in pkGroup: einverse 23 | 24 | such that: 25 | A = (f * C * h^vdoubleprime * for(i, l+1:k+l, *, g_i^x_i))^einverse 26 | -------------------------------------------------------------------------------- /src/ZKP/examples/cl-obtain-ecash.txt: -------------------------------------------------------------------------------- 1 | // obtain a CL blind signature 2 | 3 | computation: 4 | given: 5 | group: pkGroup = 6 | exponents in pkGroup: x[1:l] 7 | integers: stat, modSize 8 | compute: 9 | random integer in [0,2^(modSize + stat)): vprime 10 | C := h^vprime * for(i, 1:l, *, g_i^x_i) 11 | 12 | proof: 13 | given: 14 | group: pkGroup = 15 | // this is specific to e-cash 16 | group: comGroup = 17 | element in pkGroup: C 18 | elements in comGroup: c[1:l] 19 | for(i, 1:l, commitment to x_i: c_i = gprime^x_i * hprime^r_i) 20 | integer: l_x 21 | 22 | prove knowledge of: 23 | integers: x[1:l] 24 | exponents in comGroup: r[1:l] 25 | exponents in pkGroup: vprime 26 | 27 | such that: 28 | for(i, 1:l, range in pkGroup: (-(2^l_x - 1)) <= x_i < 2^l_x) 29 | C = h^vprime * for(i, 1:l, *, g_i^x_i) 30 | for(i, 1:l, c_i = gprime^x_i * hprime^r_i) 31 | -------------------------------------------------------------------------------- /src/ZKP/examples/cl-prove-ecash.txt: -------------------------------------------------------------------------------- 1 | // CL signature proof program 2 | 3 | computation: 4 | given: 5 | group: pkGroup = 6 | elements in pkGroup: A 7 | exponents in pkGroup: e, v, x[1:l] 8 | integers: modSize, stat 9 | compute: 10 | random integers in [0,2^(modSize + stat)): r, r_C 11 | vprime := v + r*e 12 | Aprime := A * h^r 13 | C := h^r_C * for(i, 1:l, *, g_i^x_i) 14 | D := for(i, l+1:l+k, *, g_i^x_i) 15 | // useful for not computing inverses later on 16 | fCD := f * C * D 17 | 18 | proof: 19 | given: 20 | group: pkGroup = 21 | group: comGroup = 22 | elements in pkGroup: C, D, Aprime, fCD 23 | elements in comGroup: c[1:l] 24 | for(i, 1:l, commitment to x_i: c_i = gprime^x_i * hprime^r_i) 25 | exponents in pkGroup: x[l+1:l+k] 26 | integer: l_x 27 | 28 | prove knowledge of: 29 | integers: x[1:l] 30 | exponents in comGroup: r[1:l] 31 | exponents in pkGroup: e, vprime, r_C 32 | 33 | such that: 34 | for(i, 1:l, range in pkGroup: (-(2^l_x - 1)) <= x_i < 2^l_x) 35 | C = h^r_C * for(i, 1:l, *, g_i^x_i) 36 | for(i, 1:l, c_i = gprime^x_i * hprime^r_i) 37 | fCD = (Aprime^e) * h^(r_C - vprime) 38 | -------------------------------------------------------------------------------- /src/ZKP/examples/cl.txt: -------------------------------------------------------------------------------- 1 | input: RSA_length, stat, L, x[1:m] 2 | 3 | computation: 4 | given: 5 | group: G = 6 | elements in G: A 7 | exponents in G: e, v 8 | integers: RSA_length, stat 9 | compute: 10 | random exponents in [0:2^(RSA_length + stat)): r, r_C 11 | vprime := v + r*e 12 | Aprime := A * h^r 13 | // XXX: should compute C and D externally? 14 | C := h^r_C * for(i, 1:L, *, g_i^x_i) 15 | D := prod(i, L+1:k, g_i^x_i) 16 | for(i, 1:L, &&, commitment to x_i: c_i = g^x_i * h^r_i) 17 | 18 | proof: 19 | given: 20 | group: G = 21 | elements in G: c[1:L] 22 | 23 | exponents in G: x[L+1:k] 24 | integers: l_x 25 | 26 | prove knowledge of: 27 | exponents in G: x[1:L], r[1:L], A, e, v 28 | 29 | such that: 30 | // XXX: need a way to do for each? 31 | for(i, 1:L, &&, -(2^l_x - 1) <= x_i < 2^l_x) 32 | C = for(i, 1:L, *, c_i^1 * h^(-r_i)) * h^r_C 33 | f = C^(-1) * D^(-1) * Aprime^e * h^(r_C - vprime) 34 | 35 | -------------------------------------------------------------------------------- /src/ZKP/examples/compute.txt: -------------------------------------------------------------------------------- 1 | 2 | computation: 3 | given: 4 | group: G = 5 | compute: 6 | random exponents in G: x, r_x 7 | c_x := g^x * h^r_x 8 | -------------------------------------------------------------------------------- /src/ZKP/examples/declRange.txt: -------------------------------------------------------------------------------- 1 | computation: 2 | given: 3 | group: G = 4 | compute: 5 | random exponents in G: x[1:5], r_a, r_b, r_x 6 | random integers in [0:617): a, b, c 7 | y := a+b 8 | x := x_1*x_2 9 | C_1 := g^x_1*h^r_a 10 | C_2 := g^x_2*h^r_b 11 | C_3 := g^x*h^r_x 12 | //l := for(i, 1:5, +, 3+x_i) 13 | proof: 14 | given: 15 | group: G = 16 | integers: W, y 17 | elements in G: C[1:5] 18 | commitment to x: C_3 = g^x*h^r_x 19 | commitment to x_1: C_1 = g^x_1*h^r_a 20 | commitment to x_2: C_2 = g^x_2*h^r_b 21 | prove knowledge of: 22 | exponents in G: x, r_x, x_2, r_b, x_1, r_a 23 | such that: 24 | x = x_1*x_2 25 | range: 0<=x<8 26 | 27 | -------------------------------------------------------------------------------- /src/ZKP/examples/dlr.txt: -------------------------------------------------------------------------------- 1 | 2 | computation: 3 | given: 4 | group: G = 5 | compute: 6 | random exponents in G: r, x, r_x, rando 7 | c_x := g^x * h^r_x 8 | alpha := r_x - rando * r 9 | other := (g^x * h^r_x)^x * h^alpha 10 | 11 | proof: 12 | given: 13 | group: G = 14 | elements in G: c_x, other 15 | commitment to x: c_x = g^x * h^r_x 16 | 17 | prove knowledge of: 18 | exponents in G: r, r_x, x, alpha, rando 19 | 20 | such that: 21 | other = c_x^x * h^(r_x - rando * r) 22 | -------------------------------------------------------------------------------- /src/ZKP/examples/ecash.txt: -------------------------------------------------------------------------------- 1 | // just computation (independent of proof) 2 | computation: 3 | given: 4 | group: cashGroup = 5 | exponents in cashGroup: s, t, sk_u 6 | integer: J 7 | compute: 8 | random exponents in cashGroup: r_B, r_C, r_D, x1, x2, r_y, R 9 | alpha := 1 / (s + J) 10 | beta := 1 / (t + J) 11 | C := g^s * h^r_C 12 | D := g^t * h^r_D 13 | y := h1^x1 * h2^x2 * f^r_y 14 | B := g^sk_u * h^r_B 15 | // XXX: again, should be able to automate this change later 16 | S := g^(alpha + x1) 17 | T := g^(sk_u + R*beta + x2) 18 | 19 | // for prover and verifier 20 | proof: 21 | given: 22 | group: cashGroup = 23 | element in cashGroup: y 24 | elements in cashGroup: y, S, T, B, C, D 25 | commitment to sk_u: B = g^sk_u * h^r_B 26 | commitment to s: C = g^s * h^r_C 27 | commitment to t: D = g^t * h^r_D 28 | 29 | prove knowledge of: 30 | exponents in cashGroup: x1, x2, r_y, sk_u, alpha, beta, s, t, 31 | r_B, r_C, r_D, R 32 | integer: J 33 | 34 | such that: 35 | y = h1^x1 * h2^x2 * f^r_y 36 | S = g^(alpha + x1) 37 | // XXX: doing this to get better numbers for now 38 | T = g^(sk_u + x2 + R*beta) 39 | g = (g^J * C)^alpha * h^(-r_C / (s+J)) 40 | g = (g^J * D)^beta * h^(-r_D / (t+J)) 41 | -------------------------------------------------------------------------------- /src/ZKP/examples/encrypt.txt: -------------------------------------------------------------------------------- 1 | 2 | computation: 3 | given: 4 | group: G 5 | group: RSAGroup 6 | modulus: N 7 | elements in G: f, b, a[1:m] 8 | exponents in G: x[1:m] 9 | compute: 10 | random integer in [0,N/4): r 11 | for(i, 1:m, u_i := b^x_i * a_i^r) 12 | v := f^r 13 | -------------------------------------------------------------------------------- /src/ZKP/examples/examples.txt: -------------------------------------------------------------------------------- 1 | 2 | // just computation (independent of proof) 3 | computation: 4 | given: 5 | group: rangeGroup = 6 | group: cashGroup = 7 | exponents in cashGroup: s, t, sk_u 8 | integers: J 9 | compute: 10 | random exponents in cashGroup: r_B, r_C, r_D, x[1:2], r_y 11 | random exponents in rangeGroup: r_J 12 | c_J := g1^J * g2^r_J 13 | alpha := 1 / (s + J) 14 | beta := 1 / (t + J) 15 | C := f^alpha * g^r_C 16 | D := f^beta * g^r_D 17 | y := h1^x_1 * h2^x_2 * f^r_y 18 | U := g^sk_u * h^r_B 19 | S := g^alpha * g^x_1 20 | T := g^sk_u * (g^R)^beta * g^x_2 21 | 22 | // for prover and verifier 23 | proof: 24 | given: 25 | group: rangeGroup = 26 | group: cashGroup = 27 | integers: W, low 28 | elements in cashGroup: y, S, T, C, D, U 29 | commitment to alpha: C = f^alpha * g^r_C 30 | commitment to beta: D = f^beta * g^r_D 31 | commitment to sk_u: U = g^sk_u * h^r_B 32 | elements in rangeGroup: c_J 33 | commitment to J: c_J = g1^J * g2^r_J 34 | 35 | prove knowledge of: 36 | exponents in cashGroup: x_1, x_2, r_y, sk_u, alpha, beta, s, t, 37 | r_B, r_C, r_D, R 38 | exponents in rangeGroup: r_J 39 | integers: J 40 | 41 | such that: 42 | y = h1^x1 * h2^x2 * f^r_y 43 | S = g^alpha * g^x_1 44 | T = g^sk_u * (g^R)^beta * g^x_2 45 | g = (g^J * C)^alpha * h^(-r_C / s+J) 46 | g = (g^J * D)^beta * h^(-r_D / t+J) 47 | low <= J < W 48 | CL signature on alpha, beta, sk_u 49 | 50 | ------------------------------------------------------------------------ 51 | 52 | proof: 53 | given: 54 | group: G = 55 | elements in G: v_x, v_s, v_xy, y[1:3], c[1:4] 56 | 57 | prove knowledge of: 58 | exponents in G: rho, mu, nu, H 59 | 60 | such that: 61 | v_x = v_s^rho * v_xy^(-mu) 62 | c_1 = g^mu 63 | c_2 = h^nu 64 | c_3 = y_1^nu * g^mu 65 | c_4 = (y_2 * y_3^H)^nu 66 | 67 | ------------------------------------------------------------------------ 68 | 69 | proof: 70 | given: 71 | group: Zpstar = 72 | elements in Zpstar: x[1:3] 73 | 74 | prove knowledge of: 75 | exponents in Zpstar: w[1:3] 76 | 77 | such that: 78 | x_1 = g^w_1 79 | x_2 = g^w_2 80 | x_3 = g^w_3 81 | 82 | ------------------------------------------------------------------------ 83 | 84 | computation: 85 | given: 86 | group: G = 87 | compute: 88 | random exponents in G: a, b, r_x, r_a, r_b 89 | x := a * b 90 | c_x = g^x * h^r_x 91 | c_a = g^a * h^r_a 92 | c_b = g^b * h^r_b 93 | 94 | proof: 95 | given: 96 | group: G = 97 | elements in G: c_x, c_a, c_b 98 | commitment to x: c_x = g^x * h^r_x 99 | commitment to a: c_a = g^a * h^r_a 100 | commitment to b: c_b = g^b * h^r_b 101 | 102 | prove knowledge of: 103 | exponents in G: x, a, b, r_x, r_a, r_b 104 | 105 | such that: 106 | x = a * b 107 | -------------------------------------------------------------------------------- /src/ZKP/examples/grammar.txt: -------------------------------------------------------------------------------- 1 | 2 | BASICS 3 | 4 | letter = "a" | "b" | "c" | "d" | "e" | "f" | "g" | "h" | "i" | "j" | "k" 5 | | "l" | "m" | "n" | "o" | "p" | "q" | "r" | "s" | "t" | "u" 6 | | "v" | "w" | "x" | "y" | "z" | "A" | "B" | "C" | "D" | "E" 7 | | "F" | "G" | "H" | "I" | "J" | "K" | "L" | "M" | "N" | "O" 8 | | "P" | "Q" | "R" | "S" | "T" | "U" | "V" | "W" | "X" | "Y" | "Z" 9 | digit = "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9" 10 | whitespace = " " 11 | 12 | character = letter | digit 13 | alpha_or_space = character | whitespace 14 | 15 | comment = "//", {letter} 16 | 17 | number = [ "-" ], digit, {digit} 18 | (name has to start with an alphabetic letter) 19 | ID = letter, {character} 20 | crypto_num = number | ID 21 | 22 | CLAUSES 23 | 24 | expr = sumExpr 25 | sumExpr = prodExpr, { ("+" | "-"), prodExpr } 26 | prodExpr = powExpr, { ("*" | "/"), powExpr } 27 | powExpr = atom, { "^", atom } 28 | atom = crypto_num | "(", sumExpr, ")" 29 | 30 | assignment = name, "=", expr 31 | 32 | BLOCKS 33 | 34 | namelist = name | name, ",", namelist 35 | 36 | group_name = "group:", name, "=", "<", namelist, ">" 37 | integer_name = "integers:", namelist 38 | 39 | declare_elmt_list = "elements in ", name, ":", namelist 40 | declare_exp_list = "exponents in ", name, ":", namelist 41 | declare_num_list = declare_elmt_list | declare_exp_list 42 | 43 | (can name groups, integers, elements, exponents) 44 | declaration = group_name | integer_name | declare_num_list 45 | 46 | random = "random", declare_num_list 47 | 48 | (write range as either low < x < high or as high > x > low) 49 | range = name, "<", ["="], name, "<", ["="], name 50 | | name, ">", ["="], name, ">", ["="], name 51 | | "0", "<=", name 52 | | name, ">=", "0" 53 | clsig = "CL signature on ", namelist 54 | 55 | (possible relations for now) 56 | relation = assignment | range | clsig 57 | 58 | declaration_block = declaration | declaration, "\n", {declaration} 59 | assignment_block = assignment | assignment, "\n" , assignment_block 60 | 61 | given_block = "given:", "\n", declaration_block 62 | compute_block = "compute:", "\n", {random}, assignment_block 63 | prove_block = "prove knowledge of:", "\n", declaration_block 64 | relation_block = "such that:", "\n", relation, "\n", {relation} 65 | 66 | program = [ given_block, compute_block], given_block, "\n", prove_block, "\n", 67 | relation_block 68 | -------------------------------------------------------------------------------- /src/ZKP/examples/modulus.txt: -------------------------------------------------------------------------------- 1 | 2 | computation: 3 | given: 4 | group: G 5 | modulus: n 6 | compute: 7 | random integer in [0,n/2): s 8 | plusone := n + 1 9 | -------------------------------------------------------------------------------- /src/ZKP/examples/multiplication.txt: -------------------------------------------------------------------------------- 1 | computation: 2 | given: 3 | group: G = 4 | compute: 5 | random exponents in G: a, b, r_x, r_a, r_b 6 | x := a * b 7 | c_x := g^x * h^r_x 8 | c_a := g^a * h^r_a 9 | c_b := g^b * h^r_b 10 | 11 | proof: 12 | given: 13 | group: G = 14 | elements in G: c_x, c_a, c_b 15 | commitment to x: c_x = g^x * h^r_x 16 | commitment to a: c_a = g^a * h^r_a 17 | commitment to b: c_b = g^b * h^r_b 18 | 19 | prove knowledge of: 20 | exponents in G: x, a, b, r_x, r_a, r_b 21 | 22 | such that: 23 | x = a * b 24 | -------------------------------------------------------------------------------- /src/ZKP/examples/presig.txt: -------------------------------------------------------------------------------- 1 | 2 | proof: 3 | given: 4 | group: cashGroup = 5 | elements in cashGroup: A, pk_u 6 | commitment to sk_u: A = g^sk_u * h^r_u 7 | prove knowledge of: 8 | exponent in cashGroup: sk_u, r_u 9 | such that: 10 | pk_u = g^sk_u 11 | A = g^sk_u * h^r_u 12 | -------------------------------------------------------------------------------- /src/ZKP/examples/range.txt: -------------------------------------------------------------------------------- 1 | 2 | proof: 3 | given: 4 | group: G = 5 | integers: W 6 | 7 | prove knowledge of: 8 | integers: J 9 | 10 | such that: 11 | range in G: 0 <= J < W 12 | -------------------------------------------------------------------------------- /src/ZKP/examples/simpleDLR.txt: -------------------------------------------------------------------------------- 1 | 2 | computation: 3 | given: 4 | group: G = 5 | compute: 6 | random exponents in G: x 7 | C := g^x 8 | y := 1 / x 9 | D := g^y 10 | 11 | proof: 12 | given: 13 | group: G = 14 | elements in G: C, D 15 | 16 | prove knowledge of: 17 | exponents in G: x, y 18 | 19 | such that: 20 | g = C^y 21 | -------------------------------------------------------------------------------- /src/ZKP/examples/try-range.txt: -------------------------------------------------------------------------------- 1 | 2 | computation: 3 | given: 4 | group: G = 5 | integers: J, lo, hi 6 | 7 | compute: 8 | random exponents in G: r_J, r_2 9 | c_J := g^J * h^r_J 10 | J_lo := J - lo 11 | hi_J := hi - J 12 | c_Jlo := c_J * g^(-lo) 13 | c_hiJ := g^hi * c_J^(-1) 14 | hiJJlo := Jlo * hiJ 15 | c_hiJJlo := g^hiJJlo * h^r_2 16 | 17 | proof: 18 | given: 19 | group: G = 20 | integers: W 21 | elements in G: c_J, c_Jlo, c_hiJ, c_hiJJlo 22 | commitment to J: c_J = g^J * h^r_J 23 | commitment to Jlo: c_Jlo = c_J * g^(-lo) 24 | commitment to hiJ: c_hiJ = g^hi * c_J^(-1) 25 | commitment to hiJJlo: c_hiJJlo = g^hiJJlo * h^r_2 26 | 27 | prove knowledge of: 28 | integers: J 29 | exponents in G: r_J, r_2 30 | 31 | such that: 32 | // XXX: should we complain if G isn't an RSA group? 33 | c_J = g^J * h^r_J 34 | hiJJlo = Jlo * hiJ 35 | 0 <= hiJJlo 36 | -------------------------------------------------------------------------------- /src/ZKP/examples/twoDL.txt: -------------------------------------------------------------------------------- 1 | 2 | computation: 3 | given: 4 | group: G = 5 | compute: 6 | random exponents in G: x, y, r_x, r_y 7 | c_x := g^x * h^r_x 8 | c_y := g^y * h^r_y 9 | 10 | proof: 11 | given: 12 | group: G = 13 | elements in G: c_x, c_y 14 | commitment to x: c_x = g^x * h^r_x 15 | commitment to y: c_y = g^y * h^r_y 16 | 17 | prove knowledge of: 18 | exponents in G: x, y, r_x, r_y 19 | 20 | such that: 21 | c_x = g^x * h^r_x 22 | c_y = g^y * h^r_y 23 | -------------------------------------------------------------------------------- /src/ZKP/examples/undef.txt: -------------------------------------------------------------------------------- 1 | 2 | // example where things are used but not defined 3 | 4 | proof: 5 | 6 | given: 7 | group: G = 8 | elements in G: c_x 9 | commitment to x: c_x = g1^x * g2^r_x 10 | 11 | prove knowledge of: 12 | exponents in G: x, r_x 13 | 14 | such that: 15 | x = a * b 16 | -------------------------------------------------------------------------------- /src/ZKP/examples/userid.txt: -------------------------------------------------------------------------------- 1 | 2 | proof: 3 | given: 4 | group: G = 5 | element in G: pk_u 6 | prove knowledge of: 7 | exponent in G: sk_u 8 | such that: 9 | pk_u = g^sk_u 10 | -------------------------------------------------------------------------------- /src/ZKP/examples/ve.txt: -------------------------------------------------------------------------------- 1 | // see also encrypt.txt for first part 2 | 3 | computation: 4 | given: 5 | group: secondGroup = 6 | // this group is just for specifying the modulus 7 | group: RSAGroup 8 | modulus: N 9 | group: G 10 | // XXX: this is specific to e-cash 11 | group: cashGroup = 12 | exponents in G: x[1:m] 13 | elements in G: u[1:m], v, w 14 | compute: 15 | random integer in [0,N/4): s 16 | random exponents in secondGroup: r[1:m] 17 | for (i, 1:m, c_i := g_1^x_i * g_2^r_i) 18 | Xprime := for(i, 1:m, *, g_i^x_i) * h^s 19 | // it is faster to do things this way than to have to compute inverses 20 | vsquared := v^2 21 | wsquared := w^2 22 | for(i, 1:m, usquared_i := u_i^2) 23 | 24 | proof: 25 | given: 26 | group: secondGroup = 27 | group: G 28 | group: RSAGroup 29 | modulus: N 30 | group: cashGroup = 31 | element in cashGroup: X 32 | elements in secondGroup: Xprime, c[1:m] 33 | for(i, 1:m, commitment to x_i: c_i = g_1^x_i * g_2^r_i) 34 | elements in G: a[1:m], b, d, e, f, usquared[1:m], vsquared, wsquared 35 | 36 | prove knowledge of: 37 | integers: x[1:m], r 38 | exponent in G: hash 39 | exponents in secondGroup: r[1:m], s 40 | 41 | such that: 42 | for(i, 1:m, range in secondGroup: -N/2 + 1 <= x_i < N/2) 43 | vsquared = f^(2*r) 44 | wsquared = (d * e^hash)^(2*r) 45 | for(i, 1:m, usquared_i = b^(2*x_i) * a_i^(2*r)) 46 | X = for(i, 1:m, *, f_i^x_i) 47 | Xprime = for(i, 1:m, *, g_i^x_i) * h^s 48 | -------------------------------------------------------------------------------- /src/ZKP/examples/vedecrypter.txt: -------------------------------------------------------------------------------- 1 | 2 | computation: 3 | given: 4 | group: RSAGroup 5 | modulus: N 6 | group: G 7 | element in G: f0 8 | compute: 9 | random integers in [0,N/4): x[1:3], y, z 10 | f := f0^(2*N) 11 | for(i, 1:3, a_i := f^x_i) 12 | d := f^y 13 | e := f^z 14 | b := 1 + N 15 | -------------------------------------------------------------------------------- /src/base64.h: -------------------------------------------------------------------------------- 1 | /* 2 | * File: base64.h 3 | * Author: kupcu 4 | * 5 | * Created on October 31, 2008, 6:04 PM 6 | */ 7 | 8 | #ifndef _BASE64_H 9 | #define _BASE64_H 10 | 11 | #include "NTL/ZZ.h" 12 | #include 13 | 14 | std::string base64_encode(/*unsigned*/ char const* , unsigned int len); 15 | std::string base64_decode(std::string const& s); 16 | 17 | /// base64-decode a string and turn it into a ZZ 18 | inline void b64_to_ZZ(NTL::ZZ& z, const string& str) { 19 | if (!str.size()) 20 | throw CashException(CashException::CE_IO_ERROR, 21 | "NTL::b64_to_ZZ: can't unserialize empty string"); 22 | if (str == "0") { z = 0; return; } 23 | unsigned int negsign = (str[0] == '-') ? 1 : 0; 24 | z = NTL::ZZFromBytes(base64_decode(negsign ? str.substr(1) : str)); 25 | if (negsign) { z = -z; } 26 | } 27 | inline NTL::ZZ b64_to_ZZ(const string& str) { NTL::ZZ z; b64_to_ZZ(z, str); return z; } 28 | 29 | /// take a ZZ and return a base64-encoded string 30 | inline void ZZ_to_b64(string &str, const NTL::ZZ& z) { 31 | if (z == 0) { str = "0"; return; } 32 | unsigned int blen = NTL::NumBytes(z); // NumBytes(0) => 0 33 | char buf[blen]; 34 | NTL::BytesFromZZ((unsigned char *)&buf, z, blen); 35 | str = base64_encode(buf, blen); 36 | if (z < 0) { str = "-" + str; } // add sign if negative 37 | } 38 | inline string ZZ_to_b64(const NTL::ZZ& z) { string s; ZZ_to_b64(s, z); return s; } 39 | 40 | #endif /* _BASE64_H */ 41 | 42 | -------------------------------------------------------------------------------- /src/dsa.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | // wrapper for broken DSAparams_dup macro, as in: 5 | // http://www.mail-archive.com/openssl-users@openssl.org/msg37985.html 6 | // http://napali.borg.ch/ACE/tao/ssliop/a00154.html 7 | 8 | DSA *DSAparams_dup_wrap(const DSA* dsa) 9 | { 10 | return DSAparams_dup(dsa); 11 | } 12 | -------------------------------------------------------------------------------- /src/gdbinit4x: -------------------------------------------------------------------------------- 1 | define dumpstlht 2 | set $s = $arg0._M_ht._M_buckets._M_impl._M_start 3 | set $e = $arg0._M_ht._M_buckets._M_impl._M_finish 4 | set $b = 0 5 | while $s < $e 6 | printf "bucket %d\n", $b 7 | set $x = *$s 8 | while $x != 0 9 | p $x->_M_val 10 | set $x = $x->_M_next 11 | end 12 | set $b = $b + 1 13 | set $s = $s + 1 14 | printf "\n" 15 | end 16 | end 17 | 18 | define dumpvec 19 | set $s = $arg0._M_impl._M_start 20 | set $e = $arg0._M_impl._M_finish 21 | set $i = 0 22 | while $s < $e 23 | printf "%d:", $i 24 | p *$s 25 | set $i = $i + 1 26 | set $s = $s + 1 27 | printf "\n" 28 | end 29 | end 30 | 31 | define dumpstlrbt 32 | set $h = $arg0._M_t._M_impl._M_header 33 | set $i = $h->_M_left 34 | while $i != $h 35 | p ((_Rb_tree_node*) $i)->_M_value_field 36 | if $i->_M_right != 0 37 | set $i = $i->_M_right 38 | while $i->_M_left != 0 39 | set $i = $i->_M_left 40 | end 41 | else 42 | set $p = $i->_M_parent 43 | while $i == $p->_M_right 44 | set $i = $p 45 | set $p = $p->_M_parent 46 | end 47 | if $i->_M_right != $p 48 | set $i = $p 49 | end 50 | end 51 | end 52 | end 53 | 54 | define dumpmap 55 | dumpstlrbt $arg0 56 | end 57 | 58 | define dumpset 59 | dumpstlrbt $arg0 60 | end 61 | 62 | define dumphmap 63 | dumpstlht $arg0 64 | end 65 | 66 | 67 | define dumphset 68 | dumpstlht $arg0 69 | end 70 | 71 | define dumpstr 72 | printf "[Capacity = %u, Length = %u, References = %d]\n\"%s\"\n", $arg0._M_rep()->_M_capacity, $arg0._M_rep()->_M_length, $arg0._M_rep()->_M_refcount, $arg0._M_data() 73 | end 74 | 75 | -------------------------------------------------------------------------------- /src/new_ptr.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * new_ptr: allows you to do: 3 | * new_ptr(args) 4 | * where you would usually do: 5 | * shared_ptr(new T(args)) 6 | * 7 | * from http://www.boostcookbook.com/Recipe:/1234950 8 | */ 9 | 10 | #ifndef __NEW_PTR_HPP__ 11 | #define __NEW_PTR_HPP__ 12 | 13 | #include 14 | #include 15 | #include 16 | #include 17 | 18 | #ifndef NEW_PTR_MAX_PARAMS 19 | #define NEW_PTR_MAX_PARAMS 16 20 | #endif // NEW_PTR_MAX_PARAMS 21 | 22 | #define NEW_PTR_PARAM_DECL(z, n, _) BOOST_PP_COMMA_IF(n) A ## n const & a ## n 23 | 24 | class new_ptr_access { 25 | private: 26 | template 27 | static void destroy(T* pT) { 28 | typedef char typeMustBeCompleteType[sizeof(T) ? 1 : -1]; 29 | (void)sizeof(typeMustBeCompleteType); 30 | delete pT; 31 | } 32 | 33 | #define NEW_PTR_ACCESS_CREATE_FUNCTION(z, n, _) \ 34 | template< class T BOOST_PP_ENUM_TRAILING_PARAMS(n, class A) > \ 35 | static boost::shared_ptr create(BOOST_PP_REPEAT(n, NEW_PTR_PARAM_DECL, _)) { \ 36 | return boost::shared_ptr(new T(BOOST_PP_ENUM_PARAMS(n, a)), destroy); \ 37 | } \ 38 | 39 | 40 | BOOST_PP_REPEAT(BOOST_PP_INC(NEW_PTR_MAX_PARAMS), NEW_PTR_ACCESS_CREATE_FUNCTION, _) 41 | 42 | #undef NEW_PTR_ACCESS_CREATE_FUNCTION 43 | 44 | #define NEW_PTR_ACCESS_FRIEND_DECL(z, n, _) \ 45 | template \ 46 | friend boost::shared_ptr new_ptr(BOOST_PP_REPEAT(n, NEW_PTR_PARAM_DECL, _)); \ 47 | 48 | 49 | BOOST_PP_REPEAT(BOOST_PP_INC(NEW_PTR_MAX_PARAMS), NEW_PTR_ACCESS_FRIEND_DECL, _) 50 | 51 | #undef NEW_PTR_ACCESS_FRIEND_DECL 52 | 53 | private: 54 | new_ptr_access(); 55 | }; 56 | 57 | #define NEW_PTR_FUNCTION_DECL(z, n, _) \ 58 | template< class T BOOST_PP_ENUM_TRAILING_PARAMS(n, class A)> \ 59 | boost::shared_ptr new_ptr(BOOST_PP_REPEAT(n, NEW_PTR_PARAM_DECL, _)) { \ 60 | return new_ptr_access::create(BOOST_PP_ENUM_PARAMS(n, a)); \ 61 | } \ 62 | 63 | 64 | BOOST_PP_REPEAT(BOOST_PP_INC(NEW_PTR_MAX_PARAMS), NEW_PTR_FUNCTION_DECL, _) 65 | #undef NEW_PTR_FUNCTION_DECL 66 | #undef NEW_PTR_PARAM_DECL 67 | #undef NEW_PTR_DECL 68 | 69 | /* 70 | // Example: 71 | class foo { 72 | private: 73 | foo() 74 | : name_("My Name") 75 | { } 76 | 77 | foo(const std::string name) 78 | : name_(name) 79 | { } 80 | 81 | foo(int i, int j) 82 | : name_("I & J") 83 | { } 84 | 85 | ~foo() { } 86 | 87 | friend class new_ptr_access; 88 | 89 | public: 90 | const std::string& name() const { return name_; } 91 | 92 | private: 93 | std::string name_; 94 | }; 95 | 96 | shared_ptr bar1 = new_ptr(); 97 | shared_ptr bar2 = new_ptr("example"); 98 | shared_ptr bar3 = new_ptr(1, 2); 99 | 100 | delete bar1.get(); // won't compile 101 | 102 | foo stackInstance("example"); // won't compile 103 | foo* heapInstance = new foo("example") // won't compile 104 | 105 | */ 106 | #endif 107 | -------------------------------------------------------------------------------- /src/secret.80.arbiter: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 10920825196290361573979919017621871325477378773996850640105075806008004303430566856366994394642789608719473456943556402694819754386254952818709016208993887 7 | 8 | 9 | 10037869211273525771309704095736980063138293524228969395922447631897580584680351347509774844638325663027280026515707047838439090560364004679699651900566983 10 | 11 | 12 | 3 13 | 0 14 | 15 | 7350683499885890693877609449498623028598590129927712493931778808997516304537639608934556582255406402812950263733344589895491026268106657326656143488426741367576700642569418306708910390157180909012268082942541816891467092768613605603384172220605163601235476161880210206307284650848854879851668715136129277409 16 | 17 | 18 | 20396094803255369540575126571725083542016079180020759616317784588871795907857546459191926087156687086322619580791321783356145449725277251389740700899053142223793483490518986713355365123946591497025923291143490895379567095590476712099625260266778056247497470703558881148428273007027354650751638932798795170379 19 | 20 | 21 | 14442321425211627388820706187833154073301915652503449851754134722361103544814002994442426314805842624723451327673825071487951232520862333006624374831700435054849115444125041812439602129437454484468725417650046457543084347458894690905560865776452257718033673282811201516994377961766108915748113289857542980367 22 | 23 | 24 | 25 | 1532560739724105686865205044641806279446295261802988332541831483046626037569626994124788872568904425989647929223034961246751972096720054533275993073627893106340067933939551616047089581087189963718333745709299309301984681470341801604914014270799566136030390133317167370865592497871166462033106881984556122798 26 | 27 | 28 | 8121353913349146341352359593952669525036016140890060281441290306212453948138615257076865698505846429911991141885713763378936166836794325013414040910555507602601388411350389850797644547414777935807669448018614618556093337948154046329093088925858628985979033083542543957249695387912683501239227315157673267384 29 | 30 |

31 | 10813485324999900146177592097822797299963398254687281335627554887928340780627413422086235596263283848693059198957832128912529668688295480313641490653023767 32 |

33 | 34 | 13332516921360331243318168888901315236818951886426746966188457436512652721588786416570963091139812563564046441684617810387059799511611426512420146824797419 35 | 36 |
37 |
38 | 39 | -------------------------------------------------------------------------------- /src/tool.80.user: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 80 6 | 160 7 | 8 | 855354828045887400174627068790510362312905882052 9 | 10 | 11 | 28794283913025973331815769588141583868106485627134315620122621612135021001355083428249037587375251848813991476171708978495200911688122020732431351826093395728425473901610444931078341608504688254326460670316961405945813351242983262421737723436662745733064835372410082574802232095204090082523318615201814811091 12 | 13 | 0 14 | 15 | 16 | 1 17 | 0 18 | 19 | pk_u = (g)^(sk_u) in G 20 | 21 | 61766389956936575191201774678991826422344726660619424241531957736345802477213037454198320157568791960697838532377222744888238908470617175546625291175403585151279082000579490802866843975619269579441645912387490624470317882256150027775801188922460990541150733575955350402364857551841673911962477553998986591897 22 | 23 | 24 | 25 | 26 | 1 27 | 0 28 | 29 | sk_u 30 | 31 | 1227997349131506874171458614312533840624095871804061347145029592332093732763775812056403035512799 32 | 33 | 34 | 35 | 0 36 | 37 | 1 38 | 0 39 | 40 | pk_u = (g)^(sk_u) in G 41 | 42 | 28794283913025973331815769588141583868106485627134315620122621612135021001355083428249037587375251848813991476171708978495200911688122020732431351826093395728425473901610444931078341608504688254326460670316961405945813351242983262421737723436662745733064835372410082574802232095204090082523318615201814811091 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | --------------------------------------------------------------------------------