Sign creates a recoverable ECDSA signature. The produced signature is in the 65-byte [R || S || V] format where V is 0 or 1. The caller is responsible for ensuring that msg cannot be chosen directly by an attacker. It is usually preferable to use a cryptographic hash function on any input before ha
(msg []byte, seckey []byte)
| 64 | // directly by an attacker. It is usually preferable to use a cryptographic |
| 65 | // hash function on any input before handing it to this function. |
| 66 | func Sign(msg []byte, seckey []byte) ([]byte, error) { |
| 67 | if len(msg) != 32 { |
| 68 | return nil, ErrInvalidMsgLen |
| 69 | } |
| 70 | if len(seckey) != 32 { |
| 71 | return nil, ErrInvalidKey |
| 72 | } |
| 73 | seckeydata := (*C.uchar)(unsafe.Pointer(&seckey[0])) |
| 74 | if C.secp256k1_ec_seckey_verify(context, seckeydata) != 1 { |
| 75 | return nil, ErrInvalidKey |
| 76 | } |
| 77 | |
| 78 | var ( |
| 79 | msgdata = (*C.uchar)(unsafe.Pointer(&msg[0])) |
| 80 | noncefunc = C.cql_secp256k1_nonce_function_rfc6979 |
| 81 | sigstruct C.secp256k1_ecdsa_recoverable_signature |
| 82 | ) |
| 83 | if C.secp256k1_ecdsa_sign_recoverable(context, &sigstruct, msgdata, seckeydata, noncefunc, nil) == 0 { |
| 84 | return nil, ErrSignFailed |
| 85 | } |
| 86 | |
| 87 | var ( |
| 88 | sig = make([]byte, 65) |
| 89 | sigdata = (*C.uchar)(unsafe.Pointer(&sig[0])) |
| 90 | recid C.int |
| 91 | ) |
| 92 | C.secp256k1_ecdsa_recoverable_signature_serialize_compact(context, sigdata, &recid, &sigstruct) |
| 93 | sig[64] = byte(recid) // add back recid to get 65 bytes sig |
| 94 | return sig, nil |
| 95 | } |
| 96 | |
| 97 | // RecoverPubkey returns the public key of the signer. |
| 98 | // msg must be the 32-byte hash of the message to be signed. |