exchange

Base system with REST service to issue digital coins, run by the payment service provider
Log | Files | Refs | Submodules | README | LICENSE

crypto_implementation.tex (9413B)


      1 \begin{lstlisting}[style=bfh-c,language=C,, caption={Crypto Implementation API}, label={lst:cryptoapi}]
      2     #include <sodium.h>
      3     
      4     /**
      5      * IMPLEMENTATION NOTICE:
      6      * 
      7      * This is an implementation of the Schnorr, Blind Schnorr and 
      8      * Clause Blind Schnorr Signature Scheme using Curve25519.
      9      * We use libsodium wherever possible.
     10      * 
     11      * Blind Schnorr: The Blind Schnorr Signature Scheme is BROKEN!
     12      * Use the Clause Blind Schnorr Signature Scheme instead.
     13      * 
     14      * Clause Blind Schnorr Signature Scheme:
     15      * This is a variation of the Blind Schnorr Signature Scheme where all operations
     16      * before the signature creation are performed twice.
     17      * The signer randomly chooses one of the two sessions and only creates the signature for this session.
     18      * Note that the Clause part needs to be implemented by whoever uses this API.
     19      * Further details about the Clause Blind Schnorr Signature Scheme can be found here:
     20      * https://eprint.iacr.org/2019/877.pdf
     21      */
     22     
     23     
     24     /**
     25      * Curve25519 Scalar
     26      */
     27     struct GNUNET_CRYPTO_Cs25519Scalar
     28     {
     29       /**
     30        * 32 byte scalar
     31        */
     32       unsigned char d[crypto_core_ed25519_SCALARBYTES];
     33     };
     34     
     35     
     36     /**
     37      * Curve25519 point
     38      */
     39     struct GNUNET_CRYPTO_Cs25519Point
     40     {
     41       /**
     42        * This is a point on the Curve25519.
     43        * The x coordinate can be restored using the y coordinate
     44        */
     45       unsigned char y[crypto_core_ed25519_BYTES];
     46     };
     47     
     48     
     49     /**
     50      * The private information of an Schnorr key pair.
     51      */
     52     struct GNUNET_CRYPTO_CsPrivateKey
     53     {
     54       struct GNUNET_CRYPTO_Cs25519Scalar scalar;
     55     };
     56     
     57     
     58     /**
     59      * The public information of an Schnorr key pair.
     60      */
     61     struct GNUNET_CRYPTO_CsPublicKey
     62     {
     63       struct GNUNET_CRYPTO_Cs25519Point point;
     64     };
     65     
     66     
     67     /**
     68      * Secret used for blinding (alpha and beta).
     69      */
     70     struct GNUNET_CRYPTO_CsBlindingSecret
     71     {
     72       struct GNUNET_CRYPTO_Cs25519Scalar alpha;
     73       struct GNUNET_CRYPTO_Cs25519Scalar beta;
     74     };
     75     
     76     
     77     /**
     78      * the private r used in the signature
     79      */
     80     struct GNUNET_CRYPTO_CsRSecret
     81     {
     82       struct GNUNET_CRYPTO_Cs25519Scalar scalar;
     83     };
     84     
     85     
     86     /**
     87      * the public R (derived from r) used in c
     88      */
     89     struct GNUNET_CRYPTO_CsRPublic
     90     {
     91       struct GNUNET_CRYPTO_Cs25519Point point;
     92     };
     93     
     94     /**
     95      * Schnorr c to be signed
     96      */
     97     struct GNUNET_CRYPTO_CsC
     98     {
     99       struct GNUNET_CRYPTO_Cs25519Scalar scalar;
    100     };
    101     
    102     /**
    103      * s in the signature
    104      */
    105     struct GNUNET_CRYPTO_CsS
    106     {
    107       struct GNUNET_CRYPTO_Cs25519Scalar scalar;
    108     };
    109     
    110     /**
    111      * blinded s in the signature
    112      */
    113     struct GNUNET_CRYPTO_CsBlindS
    114     {
    115       struct GNUNET_CRYPTO_Cs25519Scalar scalar;
    116     };
    117     
    118     /**
    119      * CS Signtature containing scalar s and point R
    120      */
    121     struct GNUNET_CRYPTO_CsSignature
    122     {
    123       /**
    124        * Schnorr signatures are composed of a scalar s and a curve point
    125        */
    126       struct GNUNET_CRYPTO_CsS s_scalar;
    127       struct GNUNET_CRYPTO_Cs25519Point r_point;
    128     };
    129     
    130     /**
    131      * Nonce
    132      */
    133     struct GNUNET_CRYPTO_CsNonce
    134     {
    135       /*a nonce*/
    136       unsigned char nonce[256 / 8];
    137     };
    138     
    139     
    140     /**
    141      * Create a new random private key.
    142      *
    143      * @param[out] priv where to write the fresh private key
    144      */
    145     void
    146     GNUNET_CRYPTO_cs_private_key_generate (struct GNUNET_CRYPTO_CsPrivateKey *priv);
    147     
    148     
    149     /**
    150      * Extract the public key of the given private key.
    151      *
    152      * @param priv the private key
    153      * @param[out] pub where to write the public key
    154      */
    155     void
    156     GNUNET_CRYPTO_cs_private_key_get_public (const struct GNUNET_CRYPTO_CsPrivateKey *priv,
    157                                             struct GNUNET_CRYPTO_CsPublicKey *pub);
    158     
    159     
    160     /**
    161      * Derive a new secret r pair r0 and r1.
    162      * In original papers r is generated randomly
    163      * To provide abort-idempotency, r needs to be derived but still needs to be UNPREDICTABLE
    164      * To ensure unpredictability a new nonce should be used when a new r needs to be derived.
    165      * Uses HKDF internally.
    166      * Comment: Can be done in one HKDF shot and split output.
    167      * 
    168      * @param nonce is a random nonce
    169      * @param lts is a long-term-secret in form of a private key
    170      * @param[out] r array containing derived secrets r0 and r1
    171      */
    172     void
    173     GNUNET_CRYPTO_cs_r_derive (const struct GNUNET_CRYPTO_CsNonce *nonce,
    174                               const struct GNUNET_CRYPTO_CsPrivateKey *lts,
    175                               struct GNUNET_CRYPTO_CsRSecret r[2]);
    176     
    177     
    178     /**
    179      * Extract the public R of the given secret r.
    180      *
    181      * @param r_priv the private key
    182      * @param[out] r_pub where to write the public key
    183      */
    184     void
    185     GNUNET_CRYPTO_cs_r_get_public (const struct GNUNET_CRYPTO_CsRSecret *r_priv,
    186                                   struct GNUNET_CRYPTO_CsRPublic *r_pub);
    187     
    188     
    189     /**
    190      * Derives new random blinding factors.
    191      * In original papers blinding factors are generated randomly
    192      * To provide abort-idempotency, blinding factors need to be derived but still need to be UNPREDICTABLE
    193      * To ensure unpredictability a new nonce has to be used.
    194      * Uses HKDF internally
    195      * 
    196      * @param secret is secret to derive blinding factors
    197      * @param secret_len secret length
    198      * @param[out] bs array containing the two derivedGNUNET_CRYPTO_CsBlindingSecret
    199      */
    200     void
    201     GNUNET_CRYPTO_cs_blinding_secrets_derive (const struct GNUNET_CRYPTO_CsNonce *blind_seed,
    202                                               struct GNUNET_CRYPTO_CsBlindingSecret bs[2]);
    203     
    204     
    205     /**
    206      * Calculate two blinded c's
    207      * Comment: One would be insecure due to Wagner's algorithm solving ROS
    208      * 
    209      * @param bs array of the two blinding factor structs each containing alpha and beta
    210      * @param r_pub array of the two signer's nonce R
    211      * @param pub the public key of the signer
    212      * @param msg the message to blind in preparation for signing
    213      * @param msg_len length of message msg
    214      * @param[out] blinded_c array of the two blinded c's
    215      */
    216     void
    217     GNUNET_CRYPTO_cs_calc_blinded_c (const struct GNUNET_CRYPTO_CsBlindingSecret bs[2],
    218                                         const struct GNUNET_CRYPTO_CsRPublic r_pub[2],
    219                                         const struct GNUNET_CRYPTO_CsPublicKey *pub,
    220                                         const void *msg,
    221                                         size_t msg_len,
    222                                         struct GNUNET_CRYPTO_CsC blinded_c[2]);
    223     
    224     
    225     /**
    226      * Sign a blinded c
    227      * This function derives b from a nonce and a longterm secret
    228      * In original papers b is generated randomly
    229      * To provide abort-idempotency, b needs to be derived but still need to be UNPREDICTABLE.
    230      * To ensure unpredictability a new nonce has to be used for every signature
    231      * HKDF is used internally for derivation
    232      * r0 and r1 can be derived prior by using GNUNET_CRYPTO_cs_r_derive
    233      * 
    234      * @param priv private key to use for the signing and as LTS in HKDF
    235      * @param r array of the two secret nonce from the signer
    236      * @param c array of the two blinded c to sign c_b
    237      * @param nonce is a random nonce
    238      * @param[out] blinded_signature_scalar where to write the signature
    239      * @return 0 or 1 for b (see Clause Blind Signature Scheme)
    240      */
    241     int
    242     GNUNET_CRYPTO_cs_sign_derive(const struct GNUNET_CRYPTO_CsPrivateKey *priv,
    243                                     const struct GNUNET_CRYPTO_CsRSecret r[2],
    244                                     const struct GNUNET_CRYPTO_CsC c[2],
    245                                     const struct GNUNET_CRYPTO_CsNonce *nonce,
    246                                     struct GNUNET_CRYPTO_CsBlindS *blinded_signature_scalar
    247                                     );
    248     
    249     
    250     /**
    251      * Unblind a blind-signed signature using a c that was blinded
    252      *
    253      * @param blinded_signature_scalar the signature made on the blinded c
    254      * @param bs the blinding factors used in the blinding
    255      * @param[out] signature_scalar where to write the unblinded signature
    256      */
    257     void
    258     GNUNET_CRYPTO_cs_unblind (const struct GNUNET_CRYPTO_CsBlindS *blinded_signature_scalar,
    259                                   const struct GNUNET_CRYPTO_CsBlindingSecret *bs,
    260                                   struct GNUNET_CRYPTO_CsS *signature_scalar);
    261     
    262     
    263     /**
    264      * Verify whether the given message corresponds to the given signature and the
    265      * signature is valid with respect to the given public key.
    266      *
    267      * @param sig signature that is being validated
    268      * @param pub public key of the signer
    269      * @param msg is the message that should be signed by @a sig  (message is used to calculate c)
    270      * @param msg_len is the message length
    271      * @returns #GNUNET_YES on success, #GNUNET_SYSERR if key parameter(s) invalid #GNUNET_NO if signature invalid
    272      */
    273     enum GNUNET_GenericReturnValue
    274     GNUNET_CRYPTO_cs_verify (const struct GNUNET_CRYPTO_CsSignature *sig,
    275                                   const struct GNUNET_CRYPTO_CsPublicKey *pub,
    276                                   const void *msg,
    277                                   size_t msg_len);
    278     
    279 \end{lstlisting}