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 */