aboutsummaryrefslogtreecommitdiffstats
path: root/src/lib/pubkey/ec_group
diff options
context:
space:
mode:
authorJack Lloyd <[email protected]>2020-10-20 19:17:28 -0400
committerJack Lloyd <[email protected]>2020-10-20 19:17:28 -0400
commit54ccb865195aeecd40d6081dca0dab157b9f8fa5 (patch)
tree1b2a52a81097bdbe92136a56f831d9b9f31103a6 /src/lib/pubkey/ec_group
parentf33f00e5d0add6b17c3a51407720710a58bacd0b (diff)
Fix ECC multiexponentiation when two points are related
If the points are related by x = -{1,2,3}y then an infinity was silently produced, causing validation failures. Fixes #2424
Diffstat (limited to 'src/lib/pubkey/ec_group')
-rw-r--r--src/lib/pubkey/ec_group/point_gfp.cpp6
-rw-r--r--src/lib/pubkey/ec_group/point_mul.cpp20
-rw-r--r--src/lib/pubkey/ec_group/point_mul.h1
3 files changed, 25 insertions, 2 deletions
diff --git a/src/lib/pubkey/ec_group/point_gfp.cpp b/src/lib/pubkey/ec_group/point_gfp.cpp
index c78763829..6c2302bd6 100644
--- a/src/lib/pubkey/ec_group/point_gfp.cpp
+++ b/src/lib/pubkey/ec_group/point_gfp.cpp
@@ -427,6 +427,12 @@ void PointGFp::force_all_affine(std::vector<PointGFp>& points,
return;
}
+ for(size_t i = 0; i != points.size(); ++i)
+ {
+ if(points[i].is_zero())
+ throw Invalid_State("Cannot convert zero ECC point to affine");
+ }
+
/*
For >= 2 points use Montgomery's trick
diff --git a/src/lib/pubkey/ec_group/point_mul.cpp b/src/lib/pubkey/ec_group/point_mul.cpp
index d4a0b6ee6..2dff959d7 100644
--- a/src/lib/pubkey/ec_group/point_mul.cpp
+++ b/src/lib/pubkey/ec_group/point_mul.cpp
@@ -9,6 +9,7 @@
#include <botan/reducer.h>
#include <botan/internal/rounding.h>
#include <botan/internal/ct_utils.h>
+#include <iostream>
namespace Botan {
@@ -375,7 +376,19 @@ PointGFp_Multi_Point_Precompute::PointGFp_Multi_Point_Precompute(const PointGFp&
m_M.push_back(y3.plus(x2, ws));
m_M.push_back(y3.plus(x3, ws));
- PointGFp::force_all_affine(m_M, ws[0].get_word_vector());
+ bool no_infinity = true;
+ for(auto& pt : m_M)
+ {
+ if(pt.is_zero())
+ no_infinity = false;
+ }
+
+ if(no_infinity)
+ {
+ PointGFp::force_all_affine(m_M, ws[0].get_word_vector());
+ }
+
+ m_no_infinity = no_infinity;
}
PointGFp PointGFp_Multi_Point_Precompute::multi_exp(const BigInt& z1,
@@ -402,7 +415,10 @@ PointGFp PointGFp_Multi_Point_Precompute::multi_exp(const BigInt& z1,
// This function is not intended to be const time
if(z12)
{
- H.add_affine(m_M[z12-1], ws);
+ if(m_no_infinity)
+ H.add_affine(m_M[z12-1], ws);
+ else
+ H.add(m_M[z12-1], ws);
}
}
diff --git a/src/lib/pubkey/ec_group/point_mul.h b/src/lib/pubkey/ec_group/point_mul.h
index d503f4bee..095620428 100644
--- a/src/lib/pubkey/ec_group/point_mul.h
+++ b/src/lib/pubkey/ec_group/point_mul.h
@@ -77,6 +77,7 @@ class PointGFp_Multi_Point_Precompute final
const BigInt& k2) const;
private:
std::vector<PointGFp> m_M;
+ bool m_no_infinity;
};
}