diff --git a/src/GENERATED/c/curve25519/decaf.c b/src/GENERATED/c/curve25519/decaf.c index 03d00d8..8be58db 100644 --- a/src/GENERATED/c/curve25519/decaf.c +++ b/src/GENERATED/c/curve25519/decaf.c @@ -98,11 +98,12 @@ const size_t API_NS(alignof_precomputed_s) = sizeof(big_register_t); /** Inverse. */ static void -gf_invert(gf y, const gf x) { +gf_invert(gf y, const gf x, int assert_nonzero) { gf t1, t2; gf_sqr(t1, x); // o^2 mask_t ret = gf_isr(t2, t1); // +-1/sqrt(o^2) = +-1/o - (void)ret; assert(ret); + (void)ret; + if (assert_nonzero) assert(ret); gf_sqr(t1, t2); gf_mul(t2, t1, x); // not direct to y in case of alias. gf_copy(y, t2); @@ -891,7 +892,7 @@ static void gf_batch_invert ( } gf_mul(out[0], out[n-1], in[n-1]); - gf_invert(out[0], out[0]); + gf_invert(out[0], out[0], 1); for (i=n-1; i>0; i--) { gf_mul(t1, out[i], out[0]); @@ -1148,7 +1149,7 @@ void API_NS(point_mul_by_cofactor_and_encode_like_eddsa) ( } #endif /* Affinize */ - gf_invert(z,z); + gf_invert(z,z,1); gf_mul(t,x,z); gf_mul(x,y,z); @@ -1322,7 +1323,7 @@ decaf_error_t decaf_x25519 ( /* Finish */ gf_cond_swap(x2,x3,swap); gf_cond_swap(z2,z3,swap); - gf_invert(z2,z2); + gf_invert(z2,z2,0); gf_mul(x1,x2,z2); gf_serialize(out,x1,1); mask_t nz = ~gf_eq(x1,ZERO); @@ -1361,14 +1362,14 @@ void decaf_ed25519_convert_public_key_to_x25519 ( /* u = (1+y)/(1-y)*/ gf_add(n, y, ONE); /* n = y+1 */ gf_sub(d, ONE, y); /* d = 1-y */ - gf_invert(d, d); /* d = 1/(1-y) */ + gf_invert(d, d, 0); /* d = 1/(1-y) */ gf_mul(y, n, d); /* u = (y+1)/(1-y) */ gf_serialize(x,y,1); #else /* EDDSA_USE_SIGMA_ISOGENY */ /* u = y^2 * (1-dy^2) / (1-y^2) */ gf_sqr(n,y); /* y^2*/ gf_sub(d,ONE,n); /* 1-y^2*/ - gf_invert(d,d); /* 1/(1-y^2)*/ + gf_invert(d,d,0); /* 1/(1-y^2)*/ gf_mul(y,n,d); /* y^2 / (1-y^2) */ gf_mulw(d,n,EDWARDS_D); /* dy^2*/ gf_sub(d, ONE, d); /* 1-dy^2*/ @@ -1427,7 +1428,7 @@ void decaf_x25519_derive_public_key ( * component in the input. In this function though, there isn't a cofactor * component in the input. */ - gf_invert(p->t,p->x); /* 1/x */ + gf_invert(p->t,p->x,0); /* 1/x */ gf_mul(p->z,p->t,p->y); /* y/x */ gf_sqr(p->y,p->z); /* (y/x)^2 */ #if IMAGINE_TWIST diff --git a/src/GENERATED/c/ed448goldilocks/decaf.c b/src/GENERATED/c/ed448goldilocks/decaf.c index 866c63d..5fe15c8 100644 --- a/src/GENERATED/c/ed448goldilocks/decaf.c +++ b/src/GENERATED/c/ed448goldilocks/decaf.c @@ -98,11 +98,12 @@ const size_t API_NS(alignof_precomputed_s) = sizeof(big_register_t); /** Inverse. */ static void -gf_invert(gf y, const gf x) { +gf_invert(gf y, const gf x, int assert_nonzero) { gf t1, t2; gf_sqr(t1, x); // o^2 mask_t ret = gf_isr(t2, t1); // +-1/sqrt(o^2) = +-1/o - (void)ret; assert(ret); + (void)ret; + if (assert_nonzero) assert(ret); gf_sqr(t1, t2); gf_mul(t2, t1, x); // not direct to y in case of alias. gf_copy(y, t2); @@ -891,7 +892,7 @@ static void gf_batch_invert ( } gf_mul(out[0], out[n-1], in[n-1]); - gf_invert(out[0], out[0]); + gf_invert(out[0], out[0], 1); for (i=n-1; i>0; i--) { gf_mul(t1, out[i], out[0]); @@ -1148,7 +1149,7 @@ void API_NS(point_mul_by_cofactor_and_encode_like_eddsa) ( } #endif /* Affinize */ - gf_invert(z,z); + gf_invert(z,z,1); gf_mul(t,x,z); gf_mul(x,y,z); @@ -1322,7 +1323,7 @@ decaf_error_t decaf_x448 ( /* Finish */ gf_cond_swap(x2,x3,swap); gf_cond_swap(z2,z3,swap); - gf_invert(z2,z2); + gf_invert(z2,z2,0); gf_mul(x1,x2,z2); gf_serialize(out,x1,1); mask_t nz = ~gf_eq(x1,ZERO); @@ -1361,14 +1362,14 @@ void decaf_ed448_convert_public_key_to_x448 ( /* u = (1+y)/(1-y)*/ gf_add(n, y, ONE); /* n = y+1 */ gf_sub(d, ONE, y); /* d = 1-y */ - gf_invert(d, d); /* d = 1/(1-y) */ + gf_invert(d, d, 0); /* d = 1/(1-y) */ gf_mul(y, n, d); /* u = (y+1)/(1-y) */ gf_serialize(x,y,1); #else /* EDDSA_USE_SIGMA_ISOGENY */ /* u = y^2 * (1-dy^2) / (1-y^2) */ gf_sqr(n,y); /* y^2*/ gf_sub(d,ONE,n); /* 1-y^2*/ - gf_invert(d,d); /* 1/(1-y^2)*/ + gf_invert(d,d,0); /* 1/(1-y^2)*/ gf_mul(y,n,d); /* y^2 / (1-y^2) */ gf_mulw(d,n,EDWARDS_D); /* dy^2*/ gf_sub(d, ONE, d); /* 1-dy^2*/ @@ -1427,7 +1428,7 @@ void decaf_x448_derive_public_key ( * component in the input. In this function though, there isn't a cofactor * component in the input. */ - gf_invert(p->t,p->x); /* 1/x */ + gf_invert(p->t,p->x,0); /* 1/x */ gf_mul(p->z,p->t,p->y); /* y/x */ gf_sqr(p->y,p->z); /* (y/x)^2 */ #if IMAGINE_TWIST diff --git a/src/GENERATED/include/decaf/point_255.hxx b/src/GENERATED/include/decaf/point_255.hxx index f219274..1b93573 100644 --- a/src/GENERATED/include/decaf/point_255.hxx +++ b/src/GENERATED/include/decaf/point_255.hxx @@ -223,11 +223,19 @@ public: inline Point operator* (const Precomputed &q) const DECAF_NOEXCEPT { return q * (*this); } /** Direct scalar multiplication. */ - inline SecureBuffer direct_scalarmul( - const Block &in, + inline SecureBuffer direct_scalarmul ( + const FixedBlock &in, decaf_bool_t allow_identity=DECAF_FALSE, decaf_bool_t short_circuit=DECAF_TRUE ) const /*throw(CryptoException)*/; + + /** Direct scalar multiplication. */ + inline decaf_error_t DECAF_WARN_UNUSED direct_scalarmul_noexcept( + FixedBuffer &out, + const FixedBlock &in, + decaf_bool_t allow_identity=DECAF_FALSE, + decaf_bool_t short_circuit=DECAF_TRUE + ) const DECAF_NOEXCEPT; }; /** @@ -719,7 +727,7 @@ public: /** @cond internal */ inline SecureBuffer IsoEd25519::Scalar::direct_scalarmul ( - const Block &in, + const FixedBlock &in, decaf_bool_t allow_identity, decaf_bool_t short_circuit ) const /*throw(CryptoException)*/ { @@ -731,6 +739,15 @@ inline SecureBuffer IsoEd25519::Scalar::direct_scalarmul ( } return out; } + +inline decaf_error_t IsoEd25519::Scalar::direct_scalarmul_noexcept ( + FixedBuffer &out, + const FixedBlock &in, + decaf_bool_t allow_identity, + decaf_bool_t short_circuit +) const DECAF_NOEXCEPT { + return decaf_255_direct_scalarmul(out.data(), in.data(), s, allow_identity, short_circuit); +} /** @endcond */ #undef DECAF_NOEXCEPT diff --git a/src/GENERATED/include/decaf/point_448.hxx b/src/GENERATED/include/decaf/point_448.hxx index 8c73a39..c808aba 100644 --- a/src/GENERATED/include/decaf/point_448.hxx +++ b/src/GENERATED/include/decaf/point_448.hxx @@ -223,11 +223,19 @@ public: inline Point operator* (const Precomputed &q) const DECAF_NOEXCEPT { return q * (*this); } /** Direct scalar multiplication. */ - inline SecureBuffer direct_scalarmul( - const Block &in, + inline SecureBuffer direct_scalarmul ( + const FixedBlock &in, decaf_bool_t allow_identity=DECAF_FALSE, decaf_bool_t short_circuit=DECAF_TRUE ) const /*throw(CryptoException)*/; + + /** Direct scalar multiplication. */ + inline decaf_error_t DECAF_WARN_UNUSED direct_scalarmul_noexcept( + FixedBuffer &out, + const FixedBlock &in, + decaf_bool_t allow_identity=DECAF_FALSE, + decaf_bool_t short_circuit=DECAF_TRUE + ) const DECAF_NOEXCEPT; }; /** @@ -719,7 +727,7 @@ public: /** @cond internal */ inline SecureBuffer Ed448Goldilocks::Scalar::direct_scalarmul ( - const Block &in, + const FixedBlock &in, decaf_bool_t allow_identity, decaf_bool_t short_circuit ) const /*throw(CryptoException)*/ { @@ -731,6 +739,15 @@ inline SecureBuffer Ed448Goldilocks::Scalar::direct_scalarmul ( } return out; } + +inline decaf_error_t Ed448Goldilocks::Scalar::direct_scalarmul_noexcept ( + FixedBuffer &out, + const FixedBlock &in, + decaf_bool_t allow_identity, + decaf_bool_t short_circuit +) const DECAF_NOEXCEPT { + return decaf_448_direct_scalarmul(out.data(), in.data(), s, allow_identity, short_circuit); +} /** @endcond */ #undef DECAF_NOEXCEPT diff --git a/src/per_curve/decaf.tmpl.c b/src/per_curve/decaf.tmpl.c index 776488c..dd5b415 100644 --- a/src/per_curve/decaf.tmpl.c +++ b/src/per_curve/decaf.tmpl.c @@ -87,11 +87,12 @@ const size_t API_NS(alignof_precomputed_s) = sizeof(big_register_t); /** Inverse. */ static void -gf_invert(gf y, const gf x) { +gf_invert(gf y, const gf x, int assert_nonzero) { gf t1, t2; gf_sqr(t1, x); // o^2 mask_t ret = gf_isr(t2, t1); // +-1/sqrt(o^2) = +-1/o - (void)ret; assert(ret); + (void)ret; + if (assert_nonzero) assert(ret); gf_sqr(t1, t2); gf_mul(t2, t1, x); // not direct to y in case of alias. gf_copy(y, t2); @@ -880,7 +881,7 @@ static void gf_batch_invert ( } gf_mul(out[0], out[n-1], in[n-1]); - gf_invert(out[0], out[0]); + gf_invert(out[0], out[0], 1); for (i=n-1; i>0; i--) { gf_mul(t1, out[i], out[0]); @@ -1137,7 +1138,7 @@ void API_NS(point_mul_by_cofactor_and_encode_like_eddsa) ( } #endif /* Affinize */ - gf_invert(z,z); + gf_invert(z,z,1); gf_mul(t,x,z); gf_mul(x,y,z); @@ -1311,7 +1312,7 @@ decaf_error_t decaf_x$(gf_shortname) ( /* Finish */ gf_cond_swap(x2,x3,swap); gf_cond_swap(z2,z3,swap); - gf_invert(z2,z2); + gf_invert(z2,z2,0); gf_mul(x1,x2,z2); gf_serialize(out,x1,1); mask_t nz = ~gf_eq(x1,ZERO); @@ -1350,14 +1351,14 @@ void decaf_ed$(gf_shortname)_convert_public_key_to_x$(gf_shortname) ( /* u = (1+y)/(1-y)*/ gf_add(n, y, ONE); /* n = y+1 */ gf_sub(d, ONE, y); /* d = 1-y */ - gf_invert(d, d); /* d = 1/(1-y) */ + gf_invert(d, d, 0); /* d = 1/(1-y) */ gf_mul(y, n, d); /* u = (y+1)/(1-y) */ gf_serialize(x,y,1); #else /* EDDSA_USE_SIGMA_ISOGENY */ /* u = y^2 * (1-dy^2) / (1-y^2) */ gf_sqr(n,y); /* y^2*/ gf_sub(d,ONE,n); /* 1-y^2*/ - gf_invert(d,d); /* 1/(1-y^2)*/ + gf_invert(d,d,0); /* 1/(1-y^2)*/ gf_mul(y,n,d); /* y^2 / (1-y^2) */ gf_mulw(d,n,EDWARDS_D); /* dy^2*/ gf_sub(d, ONE, d); /* 1-dy^2*/ @@ -1416,7 +1417,7 @@ void decaf_x$(gf_shortname)_derive_public_key ( * component in the input. In this function though, there isn't a cofactor * component in the input. */ - gf_invert(p->t,p->x); /* 1/x */ + gf_invert(p->t,p->x,0); /* 1/x */ gf_mul(p->z,p->t,p->y); /* y/x */ gf_sqr(p->y,p->z); /* (y/x)^2 */ #if IMAGINE_TWIST diff --git a/src/per_curve/point.tmpl.hxx b/src/per_curve/point.tmpl.hxx index df95226..9fcd07b 100644 --- a/src/per_curve/point.tmpl.hxx +++ b/src/per_curve/point.tmpl.hxx @@ -210,11 +210,19 @@ public: inline Point operator* (const Precomputed &q) const DECAF_NOEXCEPT { return q * (*this); } /** Direct scalar multiplication. */ - inline SecureBuffer direct_scalarmul( - const Block &in, + inline SecureBuffer direct_scalarmul ( + const FixedBlock &in, decaf_bool_t allow_identity=DECAF_FALSE, decaf_bool_t short_circuit=DECAF_TRUE ) const /*throw(CryptoException)*/; + + /** Direct scalar multiplication. */ + inline decaf_error_t DECAF_WARN_UNUSED direct_scalarmul_noexcept( + FixedBuffer &out, + const FixedBlock &in, + decaf_bool_t allow_identity=DECAF_FALSE, + decaf_bool_t short_circuit=DECAF_TRUE + ) const DECAF_NOEXCEPT; }; /** @@ -706,7 +714,7 @@ public: /** @cond internal */ inline SecureBuffer $(cxx_ns)::Scalar::direct_scalarmul ( - const Block &in, + const FixedBlock<$(cxx_ns)::Point::SER_BYTES> &in, decaf_bool_t allow_identity, decaf_bool_t short_circuit ) const /*throw(CryptoException)*/ { @@ -718,6 +726,15 @@ inline SecureBuffer $(cxx_ns)::Scalar::direct_scalarmul ( } return out; } + +inline decaf_error_t $(cxx_ns)::Scalar::direct_scalarmul_noexcept ( + FixedBuffer<$(cxx_ns)::Point::SER_BYTES> &out, + const FixedBlock<$(cxx_ns)::Point::SER_BYTES> &in, + decaf_bool_t allow_identity, + decaf_bool_t short_circuit +) const DECAF_NOEXCEPT { + return $(c_ns)_direct_scalarmul(out.data(), in.data(), s, allow_identity, short_circuit); +} /** @endcond */ #undef DECAF_NOEXCEPT diff --git a/test/test_decaf.cxx b/test/test_decaf.cxx index c63cd98..00405ec 100644 --- a/test/test_decaf.cxx +++ b/test/test_decaf.cxx @@ -425,6 +425,23 @@ static const uint8_t rfc7748_1000000[DhLadder::PUBLIC_BYTES]; static void test_cfrg_crypto() { Test test("CFRG crypto"); SpongeRng rng(Block("test_cfrg_crypto"),SpongeRng::DETERMINISTIC); + + { + FixedArrayBuffer base, out; + FixedArrayBuffer s1(rng); + decaf_error_t e = DhLadder::shared_secret_noexcept(out,base,s1); + if (e != DECAF_FAILURE) { + test.fail(); + printf(" Multiply by 0 didn't give an error\n"); + } + if (!out.contents_equal(base)) { + test.fail(); + printf(" Multiply by 0 didn't give 0\n"); + } + } + + + for (int i=0; i base(rng);