Skip to content

Tarak/go1.26 cgo only - #44

Open
tarakby wants to merge 11 commits into
mainfrom
tarak/go1.26-cgo-only
Open

Tarak/go1.26 cgo only#44
tarakby wants to merge 11 commits into
mainfrom
tarak/go1.26-cgo-only

Conversation

@tarakby

@tarakby tarakby commented Aug 3, 2026

Copy link
Copy Markdown
Collaborator

closes #40

  • ECDSA on P-256 is based on Go crypto standard lib implements (no changes)
  • ECDSA on SECp256k1 is based on go-etehereum/crypto/secp256k1
    • this requires cgo, CGO_ENABLED=1, in the past version SECp256k1 did not use cgo
    • signatures generation is now based on RFC6979. The signatures are therefore deterministic. Moreover they are always normalized with a lower S.
    • verification still accepts both low S and high S versions of the valid signature. Although the underlying go-ethereum verification enforces non-malleability (low S only), signatures in this package are still malleable (no change compared to prior versions).

This PR also removes the non-cgo build mode, which is used to build the library without cgo (CGO_ENABLED=0) while disabling BLS. Now that ECDSA secp256k1 also uses cgo, the non-cgo mode has very limited utility and is discontinued.

@tarakby
tarakby marked this pull request as ready for review August 6, 2026 19:42

@turbolent turbolent left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I reviewed the code from a Go-perspective, but I don't have the expertise to review the crypto changes

Comment thread ecdsa_test.go
}
}

func TestEllipticUnmarshalSecp256k1(t *testing.T) {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why was this test removed?

Comment thread ecdsa_secp256k1.go
Comment on lines +172 to +175
pkBytes := make([]byte, 1+2*pLenSecp256k1)
pkBytes[0] = ecEncodingUncompressed
// pad x and y to the field size and concatenate them
padToSizeAndConcat(pkBytes[1:], x, y, pLenSecp256k1)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks like it's duplicated in secp256k1DecodePublicKeyCompressed below. Maybe it can be factored out?

@turbolent

Copy link
Copy Markdown
Member

Could you please improve the PR title?

Comment thread ecdsa_p256.go
}

// returns a publicKeyECDSAP256 from (bytes(x) || bytes(y)) bytes
func publicKeyECDSAP256(a *ecdsaContext, XYBytes []byte) (*pubKeyECDSAP256, error) {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

a *ecdsaContext is unused. Maybe remove it or use it instead of p256Instance below

Comment thread ecdsa_secp256k1.go
// normalize the signature to low S.
// This is required because the secp256k1 package does not accept high S signatures while the package allows them.
// Rejecting high S signatures would be a breaking change with prior versions.
newSig, validS := secp256k1Instance.signatureNormalizeS(sig)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this maybe use pk.ecdsaContext?

Comment thread ecdsa.go
curveP *big.Int
// curve order
curveN *big.Int
// curve order minus 1 divided by 2 (used for signature malleability annalysis)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// curve order minus 1 divided by 2 (used for signature malleability annalysis)
// curve order minus 1 divided by 2 (used for signature malleability analysis)

Comment thread ecdsa.go
// (same slice is returned if S is already normalized)
// It assumes len(sig) == 2*nLen where nLen is the byte-length of the curve order.
// This is needed when the underlying signature verification requires S to be in the lower range (to avoid signature malleability). In this package, verification allows high S signatures to be accepted.
// The function checks that S is in the correct range [0, n-1] before normalizing it. If S is not in the correct range, the function returns a false boolean. (S will be checked against 0 in the verification function - check against N is inlcuded here)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// The function checks that S is in the correct range [0, n-1] before normalizing it. If S is not in the correct range, the function returns a false boolean. (S will be checked against 0 in the verification function - check against N is inlcuded here)
// The function checks that S is in the correct range [0, n-1] before normalizing it.
// If S is not in the correct range, the function returns a false boolean.
// (S will be checked against 0 in the verification function - check against N is included here)

Comment thread ecdsa_secp256k1.go
var _ PublicKey = (*pubKeyECDSASecp256k1)(nil)

func privateKeyECDSASecp256k1(a *ecdsaContext, dBytes []byte) *prKeyECDSASecp256k1 {
sk := &prKeyECDSASecp256k1{

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe validate, like privateKeyECDSAP256 does

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

update to go1.26

2 participants