From 9e694994681b0b2861553d0a50bca6623b546dd2 Mon Sep 17 00:00:00 2001
From: Gian Demarmels <gian@demarmels.org>
Date: Mon, 14 Feb 2022 00:03:06 +0100
Subject: CS thesis

---
 doc/cs/content/appendix/crypto_implementation.tex | 279 ++++++++++++++++++++++
 1 file changed, 279 insertions(+)
 create mode 100644 doc/cs/content/appendix/crypto_implementation.tex

(limited to 'doc/cs/content/appendix/crypto_implementation.tex')

diff --git a/doc/cs/content/appendix/crypto_implementation.tex b/doc/cs/content/appendix/crypto_implementation.tex
new file mode 100644
index 00000000..9ae9b586
--- /dev/null
+++ b/doc/cs/content/appendix/crypto_implementation.tex
@@ -0,0 +1,279 @@
+\begin{lstlisting}[style=bfh-c,language=C,, caption={Crypto Implementation API}, label={lst:cryptoapi}]
+    #include <sodium.h>
+    
+    /**
+     * IMPLEMENTATION NOTICE:
+     * 
+     * This is an implementation of the Schnorr, Blind Schnorr and 
+     * Clause Blind Schnorr Signature Scheme using Curve25519.
+     * We use libsodium wherever possible.
+     * 
+     * Blind Schnorr: The Blind Schnorr Signature Scheme is BROKEN!
+     * Use the Clause Blind Schnorr Signature Scheme instead.
+     * 
+     * Clause Blind Schnorr Signature Scheme:
+     * This is a variation of the Blind Schnorr Signature Scheme where all operations
+     * before the signature creation are performed twice.
+     * The signer randomly chooses one of the two sessions and only creates the signature for this session.
+     * Note that the Clause part needs to be implemented by whoever uses this API.
+     * Further details about the Clause Blind Schnorr Signature Scheme can be found here:
+     * https://eprint.iacr.org/2019/877.pdf
+     */
+    
+    
+    /**
+     * Curve25519 Scalar
+     */
+    struct GNUNET_CRYPTO_Cs25519Scalar
+    {
+      /**
+       * 32 byte scalar
+       */
+      unsigned char d[crypto_core_ed25519_SCALARBYTES];
+    };
+    
+    
+    /**
+     * Curve25519 point
+     */
+    struct GNUNET_CRYPTO_Cs25519Point
+    {
+      /**
+       * This is a point on the Curve25519.
+       * The x coordinate can be restored using the y coordinate
+       */
+      unsigned char y[crypto_core_ed25519_BYTES];
+    };
+    
+    
+    /**
+     * The private information of an Schnorr key pair.
+     */
+    struct GNUNET_CRYPTO_CsPrivateKey
+    {
+      struct GNUNET_CRYPTO_Cs25519Scalar scalar;
+    };
+    
+    
+    /**
+     * The public information of an Schnorr key pair.
+     */
+    struct GNUNET_CRYPTO_CsPublicKey
+    {
+      struct GNUNET_CRYPTO_Cs25519Point point;
+    };
+    
+    
+    /**
+     * Secret used for blinding (alpha and beta).
+     */
+    struct GNUNET_CRYPTO_CsBlindingSecret
+    {
+      struct GNUNET_CRYPTO_Cs25519Scalar alpha;
+      struct GNUNET_CRYPTO_Cs25519Scalar beta;
+    };
+    
+    
+    /**
+     * the private r used in the signature
+     */
+    struct GNUNET_CRYPTO_CsRSecret
+    {
+      struct GNUNET_CRYPTO_Cs25519Scalar scalar;
+    };
+    
+    
+    /**
+     * the public R (derived from r) used in c
+     */
+    struct GNUNET_CRYPTO_CsRPublic
+    {
+      struct GNUNET_CRYPTO_Cs25519Point point;
+    };
+    
+    /**
+     * Schnorr c to be signed
+     */
+    struct GNUNET_CRYPTO_CsC
+    {
+      struct GNUNET_CRYPTO_Cs25519Scalar scalar;
+    };
+    
+    /**
+     * s in the signature
+     */
+    struct GNUNET_CRYPTO_CsS
+    {
+      struct GNUNET_CRYPTO_Cs25519Scalar scalar;
+    };
+    
+    /**
+     * blinded s in the signature
+     */
+    struct GNUNET_CRYPTO_CsBlindS
+    {
+      struct GNUNET_CRYPTO_Cs25519Scalar scalar;
+    };
+    
+    /**
+     * CS Signtature containing scalar s and point R
+     */
+    struct GNUNET_CRYPTO_CsSignature
+    {
+      /**
+       * Schnorr signatures are composed of a scalar s and a curve point
+       */
+      struct GNUNET_CRYPTO_CsS s_scalar;
+      struct GNUNET_CRYPTO_Cs25519Point r_point;
+    };
+    
+    /**
+     * Nonce
+     */
+    struct GNUNET_CRYPTO_CsNonce
+    {
+      /*a nonce*/
+      unsigned char nonce[256 / 8];
+    };
+    
+    
+    /**
+     * Create a new random private key.
+     *
+     * @param[out] priv where to write the fresh private key
+     */
+    void
+    GNUNET_CRYPTO_cs_private_key_generate (struct GNUNET_CRYPTO_CsPrivateKey *priv);
+    
+    
+    /**
+     * Extract the public key of the given private key.
+     *
+     * @param priv the private key
+     * @param[out] pub where to write the public key
+     */
+    void
+    GNUNET_CRYPTO_cs_private_key_get_public (const struct GNUNET_CRYPTO_CsPrivateKey *priv,
+                                            struct GNUNET_CRYPTO_CsPublicKey *pub);
+    
+    
+    /**
+     * Derive a new secret r pair r0 and r1.
+     * In original papers r is generated randomly
+     * To provide abort-idempotency, r needs to be derived but still needs to be UNPREDICTABLE
+     * To ensure unpredictability a new nonce should be used when a new r needs to be derived.
+     * Uses HKDF internally.
+     * Comment: Can be done in one HKDF shot and split output.
+     * 
+     * @param nonce is a random nonce
+     * @param lts is a long-term-secret in form of a private key
+     * @param[out] r array containing derived secrets r0 and r1
+     */
+    void
+    GNUNET_CRYPTO_cs_r_derive (const struct GNUNET_CRYPTO_CsNonce *nonce,
+                              const struct GNUNET_CRYPTO_CsPrivateKey *lts,
+                              struct GNUNET_CRYPTO_CsRSecret r[2]);
+    
+    
+    /**
+     * Extract the public R of the given secret r.
+     *
+     * @param r_priv the private key
+     * @param[out] r_pub where to write the public key
+     */
+    void
+    GNUNET_CRYPTO_cs_r_get_public (const struct GNUNET_CRYPTO_CsRSecret *r_priv,
+                                  struct GNUNET_CRYPTO_CsRPublic *r_pub);
+    
+    
+    /**
+     * Derives new random blinding factors.
+     * In original papers blinding factors are generated randomly
+     * To provide abort-idempotency, blinding factors need to be derived but still need to be UNPREDICTABLE
+     * To ensure unpredictability a new nonce has to be used.
+     * Uses HKDF internally
+     * 
+     * @param secret is secret to derive blinding factors
+     * @param secret_len secret length
+     * @param[out] bs array containing the two derivedGNUNET_CRYPTO_CsBlindingSecret
+     */
+    void
+    GNUNET_CRYPTO_cs_blinding_secrets_derive (const struct GNUNET_CRYPTO_CsNonce *blind_seed,
+                                              struct GNUNET_CRYPTO_CsBlindingSecret bs[2]);
+    
+    
+    /**
+     * Calculate two blinded c's
+     * Comment: One would be insecure due to Wagner's algorithm solving ROS
+     * 
+     * @param bs array of the two blinding factor structs each containing alpha and beta
+     * @param r_pub array of the two signer's nonce R
+     * @param pub the public key of the signer
+     * @param msg the message to blind in preparation for signing
+     * @param msg_len length of message msg
+     * @param[out] blinded_c array of the two blinded c's
+     */
+    void
+    GNUNET_CRYPTO_cs_calc_blinded_c (const struct GNUNET_CRYPTO_CsBlindingSecret bs[2],
+                                        const struct GNUNET_CRYPTO_CsRPublic r_pub[2],
+                                        const struct GNUNET_CRYPTO_CsPublicKey *pub,
+                                        const void *msg,
+                                        size_t msg_len,
+                                        struct GNUNET_CRYPTO_CsC blinded_c[2]);
+    
+    
+    /**
+     * Sign a blinded c
+     * This function derives b from a nonce and a longterm secret
+     * In original papers b is generated randomly
+     * To provide abort-idempotency, b needs to be derived but still need to be UNPREDICTABLE.
+     * To ensure unpredictability a new nonce has to be used for every signature
+     * HKDF is used internally for derivation
+     * r0 and r1 can be derived prior by using GNUNET_CRYPTO_cs_r_derive
+     * 
+     * @param priv private key to use for the signing and as LTS in HKDF
+     * @param r array of the two secret nonce from the signer
+     * @param c array of the two blinded c to sign c_b
+     * @param nonce is a random nonce
+     * @param[out] blinded_signature_scalar where to write the signature
+     * @return 0 or 1 for b (see Clause Blind Signature Scheme)
+     */
+    int
+    GNUNET_CRYPTO_cs_sign_derive(const struct GNUNET_CRYPTO_CsPrivateKey *priv,
+                                    const struct GNUNET_CRYPTO_CsRSecret r[2],
+                                    const struct GNUNET_CRYPTO_CsC c[2],
+                                    const struct GNUNET_CRYPTO_CsNonce *nonce,
+                                    struct GNUNET_CRYPTO_CsBlindS *blinded_signature_scalar
+                                    );
+    
+    
+    /**
+     * Unblind a blind-signed signature using a c that was blinded
+     *
+     * @param blinded_signature_scalar the signature made on the blinded c
+     * @param bs the blinding factors used in the blinding
+     * @param[out] signature_scalar where to write the unblinded signature
+     */
+    void
+    GNUNET_CRYPTO_cs_unblind (const struct GNUNET_CRYPTO_CsBlindS *blinded_signature_scalar,
+                                  const struct GNUNET_CRYPTO_CsBlindingSecret *bs,
+                                  struct GNUNET_CRYPTO_CsS *signature_scalar);
+    
+    
+    /**
+     * Verify whether the given message corresponds to the given signature and the
+     * signature is valid with respect to the given public key.
+     *
+     * @param sig signature that is being validated
+     * @param pub public key of the signer
+     * @param msg is the message that should be signed by @a sig  (message is used to calculate c)
+     * @param msg_len is the message length
+     * @returns #GNUNET_YES on success, #GNUNET_SYSERR if key parameter(s) invalid #GNUNET_NO if signature invalid
+     */
+    enum GNUNET_GenericReturnValue
+    GNUNET_CRYPTO_cs_verify (const struct GNUNET_CRYPTO_CsSignature *sig,
+                                  const struct GNUNET_CRYPTO_CsPublicKey *pub,
+                                  const void *msg,
+                                  size_t msg_len);
+    
+\end{lstlisting}
\ No newline at end of file
-- 
cgit v1.2.3

