Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

secp256k1: Expose Jacobian point equivalency func. #3436

Merged
merged 5 commits into from
Sep 6, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions dcrec/secp256k1/curve.go
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,20 @@ func (p *JacobianPoint) ToAffine() {
p.Y.Normalize()
}

// EquivalentNonConst returns whether or not two Jacobian points represent the
// same affine point in *non-constant* time.
func (p *JacobianPoint) EquivalentNonConst(other *JacobianPoint) bool {
// Since the point at infinity is the identity element for the group, note
// that P = P + ∞ trivially implies that P - P = ∞.
//
// Use that fact to determine if the points represent the same affine point.
var result JacobianPoint
result.Set(p)
result.Y.Normalize().Negate(1).Normalize()
AddNonConst(&result, other, &result)
return (result.X.IsZero() && result.Y.IsZero()) || result.Z.IsZero()
}

// addZ1AndZ2EqualsOne adds two Jacobian points that are already known to have
// z values of 1 and stores the result in the provided result param. That is to
// say result = p1 + p2. It performs faster addition than the generic add
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -167,46 +167,25 @@ func BenchmarkNAF(b *testing.B) {
}
}

// BenchmarkPubKeyDecompress benchmarks how long it takes to decompress the y
// coordinate from a given public key x coordinate.
func BenchmarkPubKeyDecompress(b *testing.B) {
// Randomly generated keypair.
// Private key: 9e0699c91ca1e3b7e3c9ba71eb71c89890872be97576010fe593fbf3fd57e66d
pubKeyX := new(FieldVal).SetHex("d2e670a19c6d753d1a6d8b20bd045df8a08fb162cf508956c31268c6d81ffdab")

b.ReportAllocs()
b.ResetTimer()
var y FieldVal
for i := 0; i < b.N; i++ {
_ = DecompressY(pubKeyX, false, &y)
}
}

// BenchmarkParsePubKeyCompressed benchmarks how long it takes to parse a
// compressed public key with an even y coordinate.
func BenchmarkParsePubKeyCompressed(b *testing.B) {
format := "02"
x := "ce0b14fb842b1ba549fdd675c98075f12e9c510f8ef52bd021a9a1f4809d3b4d"
pubKeyBytes := hexToBytes(format + x)

b.ReportAllocs()
b.ResetTimer()
for i := 0; i < b.N; i++ {
ParsePubKey(pubKeyBytes)
}
}

// BenchmarkParsePubKeyUncompressed benchmarks how long it takes to parse an
// uncompressed public key.
func BenchmarkParsePubKeyUncompressed(b *testing.B) {
format := "04"
x := "11db93e1dcdb8a016b49840f8c53bc1eb68a382e97b1482ecad7b148a6909a5c"
y := "b2e0eaddfb84ccf9744464f82e160bfa9b8b64f9d4c03f999b8643f656b412a3"
pubKeyBytes := hexToBytes(format + x + y)
// BenchmarkJacobianPointEquivalency benchmarks determining if two Jacobian
// points represent the same affine point.
func BenchmarkJacobianPointEquivalency(b *testing.B) {
// Create two Jacobian points with different Z values that represent the
// same affine point.
point1 := jacobianPointFromHex(
"d3e5183c393c20e4f464acf144ce9ae8266a82b67f553af33eb37e88e7fd2718",
"5b8f54deb987ec491fb692d3d48f3eebb9454b034365ad480dda0cf079651190",
"2",
)
point2 := jacobianPointFromHex(
"dcc3768780c74a0325e2851edad0dc8a566fa61a9e7fc4a34d13dcb509f99bc7",
"3503be6fb22abd76cb082f8aed63745b9149dd2b037728d32ebfebac99b51f17",
"3",
)

b.ReportAllocs()
b.ResetTimer()
for i := 0; i < b.N; i++ {
ParsePubKey(pubKeyBytes)
point1.EquivalentNonConst(&point2)
}
}
Loading