I am checking how the Ethereum handles signing but I can't figure out why the math.PaddedBigBytes is necessary:

func Sign(digestHash []byte, prv *ecdsa.PrivateKey) (sig []byte, err error) {
    if len(digestHash) != DigestLength {
        return nil, fmt.Errorf("hash is required to be exactly %d bytes (%d)", DigestLength, len(digestHash))
    seckey := math.PaddedBigBytes(prv.D, prv.Params().BitSize/8)
    defer zeroBytes(seckey)
    return secp256k1.Sign(digestHash, seckey)

Does it have to do something with the intention to generate a 65 bytes sig length?


They take the private key prv.D and pad zeroes to the most significant Bytes of the key, so that it will have the correct length, as specified in prv.Params().BitSize (bits) or prv.Params().BitSize./8 (Bytes). In that case, since we use the curve secp256k1, the private key will always we padded to 32 Bytes length.


Real private key is 0040408ca91387a405889c367fd2dc38884a15e45d7ac910bbe3db46d9b82fe5

as it seems, the developer who created that code supposed that it can be stored with the most significant Bytes truncated. If you interpret the private key as a number, this can happen, since the most significant (zero) Bytes do not change the value of the number in that case.

prv.D = 40408ca91387a405889c367fd2dc38884a15e45d7ac910bbe3db46d9b82fe5

seckey := math.PaddedBigBytes(prv.D, prv.Params().BitSize/8)

seckey = 0040408ca91387a405889c367fd2dc38884a15e45d7ac910bbe3db46d9b82fe5

EDIT: Changed a typo in prv.D

| improve this answer | |
  • I see. Thanks for explanation! – Lukas Lukac Feb 24 at 11:11

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.