github.com/karalabe/go-ethereum@v0.8.5/crypto/secp256k1/notes.go (about)

     1  package secp256k1
     2  
     3  /*
     4  <HaltingState> sipa, int secp256k1_ecdsa_pubkey_create(unsigned char *pubkey, int *pubkeylen, const unsigned char *seckey, int compressed);
     5  <HaltingState> is that how i generate private/public keys?
     6  <sipa> HaltingState: you pass in a random 32-byte string as seckey
     7  <sipa> HaltingState: if it is valid, the corresponding pubkey is put in pubkey
     8  <sipa> and true is returned
     9  <sipa> otherwise, false is returned
    10  <sipa> around 1 in 2^128 32-byte strings are invalid, so the odds of even ever seeing one is extremely rare
    11  
    12  <sipa> private keys are mathematically numbers
    13  <sipa> each has a corresponding point on the curve as public key
    14  <sipa> a private key is just a number
    15  <sipa> a public key is a point with x/y coordinates
    16  <sipa> almost every 256-bit number is a valid private key (one with a point on the curve corresponding to it)
    17  <sipa> HaltingState: ok?
    18  
    19  <sipa> more than half of random points are not on the curve
    20  <sipa> and actually, it is less than  the square root, not less than half, sorry :)
    21  !!!
    22  <sipa> a private key is a NUMBER
    23  <sipa> a public key is a POINT
    24  <gmaxwell> half the x,y values in the field are not on the curve, a private key is an integer.
    25  
    26  <sipa> HaltingState: yes, n,q = private keys; N,Q = corresponding public keys (N=n*G, Q=q*G); then it follows that n*Q = n*q*G = q*n*G = q*N
    27  <sipa> that's the reason ECDH works
    28  <sipa> multiplication is associative and commutativ
    29  */
    30  
    31  /*
    32  <HaltingState> sipa, ok; i am doing compact signatures and I want to know; can someone change the signature to get another valid signature for same message without the private key
    33  <HaltingState> because i know they can do that for the normal 72 byte signatures that openssl was putting out
    34  <sipa> HaltingState: if you don't enforce non-malleability, yes
    35  <sipa> HaltingState: if you force the highest bit of t
    36  
    37  <sipa> it _creates_ signatures that already satisfy that condition
    38  <sipa> but it will accept ones that don't
    39  <sipa> maybe i should change that, and be strict
    40  <HaltingState> yes; i want some way to know signature is valid but fails malleability
    41  <sipa> well if the highest bit of S is 1, you can take its complement
    42  <sipa> and end up with a valid signature
    43  <sipa> that is canonical
    44  */
    45  
    46  /*
    47  
    48  <HaltingState> sipa, I am signing messages and highest bit of the compact signature is 1!!!
    49  <HaltingState>  if (b & 0x80) == 0x80 {
    50  <HaltingState>   log.Panic("b= %v b2= %v \n", b, b&0x80)
    51  <HaltingState>  }
    52  <sipa> what bit?
    53  * Pengoo has quit (Ping timeout: 272 seconds)
    54  <HaltingState> the highest bit of the first byte of signature
    55  <sipa> it's the highest bit of S
    56  <sipa> so the 32nd byte
    57  <HaltingState> wtf
    58  
    59  */
    60  
    61  /*
    62   For instance, nonces are used in HTTP digest access authentication to calculate an MD5 digest
    63   of the password. The nonces are different each time the 401 authentication challenge
    64   response code is presented, thus making replay attacks virtually impossible.
    65  
    66  can verify client/server match without sending password over network
    67  */
    68  
    69  /*
    70  <hanihani> one thing I dont get about armory for instance,
    71  is how the hot-wallet can generate new addresses without
    72  knowing the master key
    73  */
    74  
    75  /*
    76  <HaltingState> i am yelling at the telehash people for using secp256r1
    77  instead of secp256k1; they thing r1 is "more secure" despite fact that
    78  there is no implementation that works and wrapping it is now taking
    79  up massive time, lol
    80  <gmaxwell> ...
    81  
    82  <gmaxwell> You know that the *r curves are selected via an undisclosed
    83  secret process, right?
    84  <gmaxwell> HaltingState: telehash is offtopic for this channel.
    85  */
    86  /*
    87   For instance, nonces are used in HTTP digest access authentication to calculate an MD5 digest
    88   of the password. The nonces are different each time the 401 authentication challenge
    89   response code is presented, thus making replay attacks virtually impossible.
    90  
    91  can verify client/server match without sending password over network
    92  */
    93  
    94  /*
    95  void secp256k1_start(void);
    96  void secp256k1_stop(void);
    97  
    98   * Verify an ECDSA signature.
    99   *  Returns: 1: correct signature
   100   *           0: incorrect signature
   101   *          -1: invalid public key
   102   *          -2: invalid signature
   103   *
   104  int secp256k1_ecdsa_verify(const unsigned char *msg, int msglen,
   105                             const unsigned char *sig, int siglen,
   106                             const unsigned char *pubkey, int pubkeylen);
   107  
   108  http://www.nilsschneider.net/2013/01/28/recovering-bitcoin-private-keys.html
   109  
   110  Why did this work? ECDSA requires a random number for each signature. If this random
   111  number is ever used twice with the same private key it can be recovered.
   112  This transaction was generated by a hardware bitcoin wallet using a pseudo-random number
   113  generator that was returning the same “random” number every time.
   114  
   115  Nonce is 32 bytes?
   116  
   117   * Create an ECDSA signature.
   118   *  Returns: 1: signature created
   119   *           0: nonce invalid, try another one
   120   *  In:      msg:    the message being signed
   121   *           msglen: the length of the message being signed
   122   *           seckey: pointer to a 32-byte secret key (assumed to be valid)
   123   *           nonce:  pointer to a 32-byte nonce (generated with a cryptographic PRNG)
   124   *  Out:     sig:    pointer to a 72-byte array where the signature will be placed.
   125   *           siglen: pointer to an int, which will be updated to the signature length (<=72).
   126   *
   127  int secp256k1_ecdsa_sign(const unsigned char *msg, int msglen,
   128                           unsigned char *sig, int *siglen,
   129                           const unsigned char *seckey,
   130                           const unsigned char *nonce);
   131  
   132  
   133   * Create a compact ECDSA signature (64 byte + recovery id).
   134   *  Returns: 1: signature created
   135   *           0: nonce invalid, try another one
   136   *  In:      msg:    the message being signed
   137   *           msglen: the length of the message being signed
   138   *           seckey: pointer to a 32-byte secret key (assumed to be valid)
   139   *           nonce:  pointer to a 32-byte nonce (generated with a cryptographic PRNG)
   140   *  Out:     sig:    pointer to a 64-byte array where the signature will be placed.
   141   *           recid:  pointer to an int, which will be updated to contain the recovery id.
   142   *
   143  int secp256k1_ecdsa_sign_compact(const unsigned char *msg, int msglen,
   144                                   unsigned char *sig64,
   145                                   const unsigned char *seckey,
   146                                   const unsigned char *nonce,
   147                                   int *recid);
   148  
   149   * Recover an ECDSA public key from a compact signature.
   150   *  Returns: 1: public key succesfully recovered (which guarantees a correct signature).
   151   *           0: otherwise.
   152   *  In:      msg:        the message assumed to be signed
   153   *           msglen:     the length of the message
   154   *           compressed: whether to recover a compressed or uncompressed pubkey
   155   *           recid:      the recovery id (as returned by ecdsa_sign_compact)
   156   *  Out:     pubkey:     pointer to a 33 or 65 byte array to put the pubkey.
   157   *           pubkeylen:  pointer to an int that will contain the pubkey length.
   158   *
   159  
   160  recovery id is between 0 and 3
   161  
   162  int secp256k1_ecdsa_recover_compact(const unsigned char *msg, int msglen,
   163                                      const unsigned char *sig64,
   164                                      unsigned char *pubkey, int *pubkeylen,
   165                                      int compressed, int recid);
   166  
   167  
   168   * Verify an ECDSA secret key.
   169   *  Returns: 1: secret key is valid
   170   *           0: secret key is invalid
   171   *  In:      seckey: pointer to a 32-byte secret key
   172   *
   173  int secp256k1_ecdsa_seckey_verify(const unsigned char *seckey);
   174  
   175  ** Just validate a public key.
   176   *  Returns: 1: valid public key
   177   *           0: invalid public key
   178   *
   179  int secp256k1_ecdsa_pubkey_verify(const unsigned char *pubkey, int pubkeylen);
   180  
   181  ** Compute the public key for a secret key.
   182   *  In:     compressed: whether the computed public key should be compressed
   183   *          seckey:     pointer to a 32-byte private key.
   184   *  Out:    pubkey:     pointer to a 33-byte (if compressed) or 65-byte (if uncompressed)
   185   *                      area to store the public key.
   186   *          pubkeylen:  pointer to int that will be updated to contains the pubkey's
   187   *                      length.
   188   *  Returns: 1: secret was valid, public key stores
   189   *           0: secret was invalid, try again.
   190   *
   191  int secp256k1_ecdsa_pubkey_create(unsigned char *pubkey, int *pubkeylen, const unsigned char *seckey, int compressed);
   192  */