From e7b5e20d147f9861b4b063d6441c21695c32e76a Mon Sep 17 00:00:00 2001 From: greg7mdp Date: Mon, 1 Apr 2024 11:02:18 -0400 Subject: [PATCH 1/8] Accept `check`/`raw` parameters in struct, so that we can pass self-documenting aggregate initializer. --- bench/eth_bench.cpp | 36 +++++++++--------- include/bls12-381/fp.hpp | 29 +++++++++++---- include/bls12-381/g.hpp | 30 ++++++++------- src/fp.cpp | 52 +++++++++++++------------- src/g.cpp | 80 ++++++++++++++++++++++------------------ test/unittests.cpp | 36 +++++++++--------- 6 files changed, 144 insertions(+), 119 deletions(-) diff --git a/bench/eth_bench.cpp b/bench/eth_bench.cpp index 41ddf9b..282046e 100644 --- a/bench/eth_bench.cpp +++ b/bench/eth_bench.cpp @@ -203,25 +203,25 @@ void benchG1Add2() { constexpr int numIters = 10000; g1 pbak = random_g1(); - auto performTest = [pbak](bool check, bool raw) { + auto performTest = [pbak](conv_opt opt) { array pRaw = {}; g1 p = pbak; - p.toJacobianBytesLE(pRaw, raw); + p.toJacobianBytesLE(pRaw, opt.raw); auto start = startStopwatch(); for (int i = 0; i < numIters; i++) { - p = *g1::fromJacobianBytesLE(pRaw, check, raw); + p = *g1::fromJacobianBytesLE(pRaw, opt); p.addAssign(p); - p.toJacobianBytesLE(pRaw, raw); + p.toJacobianBytesLE(pRaw, opt.raw); } - endStopwatch(string("check=") + std::to_string(check) + string(", raw=") + std::to_string(raw), start, numIters); + endStopwatch(string("check=") + std::to_string(opt.check) + string(", raw=") + std::to_string(opt.raw), start, numIters); }; - performTest(true, true); - performTest(true, false); - performTest(false, true); - performTest(false, false); + performTest({ .check = true, .raw = true }); + performTest({ .check = true, .raw = false }); + performTest({ .check = false, .raw = true }); + performTest({ .check = false, .raw = false }); } @@ -232,25 +232,25 @@ void benchG2Add2() { constexpr int numIters = 10000; g2 pbak = random_g2(); - auto performTest = [pbak](bool check, bool raw) { + auto performTest = [pbak](conv_opt opt) { array pRaw = {}; g2 p = pbak; - p.toJacobianBytesLE(pRaw, raw); + p.toJacobianBytesLE(pRaw, opt.raw); auto start = startStopwatch(); for (int i = 0; i < numIters; i++) { - p = *g2::fromJacobianBytesLE(pRaw, check, raw); + p = *g2::fromJacobianBytesLE(pRaw, opt); p.addAssign(p); - p.toJacobianBytesLE(pRaw, raw); + p.toJacobianBytesLE(pRaw, opt.raw); } - endStopwatch(string("check=") + std::to_string(check) + string(", raw=") + std::to_string(raw), start, numIters); + endStopwatch(string("check=") + std::to_string(opt.check) + string(", raw=") + std::to_string(opt.raw), start, numIters); }; - performTest(true, true); - performTest(true, false); - performTest(false, true); - performTest(false, false); + performTest({ .check = true, .raw = true }); + performTest({ .check = true, .raw = false }); + performTest({ .check = false, .raw = true }); + performTest({ .check = false, .raw = false }); } diff --git a/include/bls12-381/fp.hpp b/include/bls12-381/fp.hpp index 4b77374..da2bb4c 100644 --- a/include/bls12-381/fp.hpp +++ b/include/bls12-381/fp.hpp @@ -11,6 +11,11 @@ namespace bls12_381 { +struct conv_opt { + bool check; + bool raw; // no conversion to/from montgomery form +}; + // element representation of 'fp' field which is the base field class fp { @@ -21,8 +26,10 @@ class fp fp(); explicit fp(const std::array& d); fp(const fp& e); - static std::optional fromBytesBE(const std::span in, const bool check = true, const bool raw = false); - static std::optional fromBytesLE(const std::span in, const bool check = true, const bool raw = false); + static std::optional fromBytesBE(const std::span in, + const conv_opt opt = { .check = true, .raw = false }); + static std::optional fromBytesLE(const std::span in, + const conv_opt opt = { .check = true, .raw = false }); void toBytesBE(const std::span out, const bool raw = false) const; void toBytesLE(const std::span out, const bool raw = false) const; std::array toBytesBE(const bool raw = false) const; @@ -107,8 +114,10 @@ class fp2 fp2(); explicit fp2(const std::array& e2); fp2(const fp2& e); - static std::optional fromBytesBE(const std::span in, const bool check = true, const bool raw = false); - static std::optional fromBytesLE(const std::span in, const bool check = true, const bool raw = false); + static std::optional fromBytesBE(const std::span in, + const conv_opt opt = { .check = true, .raw = false }); + static std::optional fromBytesLE(const std::span in, + const conv_opt opt = { .check = true, .raw = false }); void toBytesBE(const std::span out, const bool raw = false) const; void toBytesLE(const std::span out, const bool raw = false) const; std::array toBytesBE(const bool raw = false) const; @@ -166,8 +175,10 @@ class fp6 fp6(); explicit fp6(const std::array& e3); fp6(const fp6& e); - static std::optional fromBytesBE(const std::span in, const bool check = true, const bool raw = false); - static std::optional fromBytesLE(const std::span in, const bool check = true, const bool raw = false); + static std::optional fromBytesBE(const std::span in, + const conv_opt opt = { .check = true, .raw = false }); + static std::optional fromBytesLE(const std::span in, + const conv_opt opt = { .check = true, .raw = false }); void toBytesBE(const std::span out, const bool raw = false) const; void toBytesLE(const std::span out, const bool raw = false) const; std::array toBytesBE(const bool raw = false) const; @@ -214,8 +225,10 @@ class fp12 fp12(); explicit fp12(const std::array& e2); fp12(const fp12& e); - static std::optional fromBytesBE(const std::span in, const bool check = true, const bool raw = false); - static std::optional fromBytesLE(const std::span in, const bool check = true, const bool raw = false); + static std::optional fromBytesBE(const std::span in, + const conv_opt opt = { .check = true, .raw = false }); + static std::optional fromBytesLE(const std::span in, + const conv_opt opt = { .check = true, .raw = false }); void toBytesBE(const std::span out, const bool raw = false) const; void toBytesLE(const std::span out, const bool raw = false) const; std::array toBytesBE(const bool raw = false) const; diff --git a/include/bls12-381/g.hpp b/include/bls12-381/g.hpp index 9daad3a..1bfb986 100644 --- a/include/bls12-381/g.hpp +++ b/include/bls12-381/g.hpp @@ -4,15 +4,11 @@ #include #include #include +#include "fp.hpp" namespace bls12_381 { -class fp; -class fp2; -class fp6; -class fp12; - // g1 is type for point in G1. // g1 is both used for Affine and Jacobian point representation. // If z is equal to one the point is considered as in affine form. @@ -27,10 +23,14 @@ class g1 g1(); explicit g1(const std::array& e3); g1(const g1& e); - static std::optional fromJacobianBytesBE(const std::span in, const bool check = false, const bool raw = false); - static std::optional fromJacobianBytesLE(const std::span in, const bool check = false, const bool raw = false); - static std::optional fromAffineBytesBE(const std::span in, const bool check = false, const bool raw = false); - static std::optional fromAffineBytesLE(const std::span in, const bool check = false, const bool raw = false); + static std::optional fromJacobianBytesBE(const std::span in, + conv_opt opt = { .check = false, .raw = false }); + static std::optional fromJacobianBytesLE(const std::span in, + conv_opt opt = { .check = false, .raw = false }); + static std::optional fromAffineBytesBE(const std::span in, + conv_opt opt = { .check = false, .raw = false }); + static std::optional fromAffineBytesLE(const std::span in, + conv_opt opt = { .check = false, .raw = false }); static std::optional fromCompressedBytesBE(const std::span in); void toJacobianBytesBE(const std::span out, const bool raw = false) const; void toJacobianBytesLE(const std::span out, const bool raw = false) const; @@ -89,10 +89,14 @@ class g2 g2(); explicit g2(const std::array& e3); g2(const g2& e); - static std::optional fromJacobianBytesBE(const std::span in, const bool check = false, const bool raw = false); - static std::optional fromJacobianBytesLE(const std::span in, const bool check = false, const bool raw = false); - static std::optional fromAffineBytesBE(const std::span in, const bool check = false, const bool raw = false); - static std::optional fromAffineBytesLE(const std::span in, const bool check = false, const bool raw = false); + static std::optional fromJacobianBytesBE(const std::span in, + conv_opt opt = { .check = false, .raw = false }); + static std::optional fromJacobianBytesLE(const std::span in, + conv_opt opt = { .check = false, .raw = false }); + static std::optional fromAffineBytesBE(const std::span in, + conv_opt opt = { .check = false, .raw = false }); + static std::optional fromAffineBytesLE(const std::span in, + conv_opt opt = { .check = false, .raw = false }); static std::optional fromCompressedBytesBE(const std::span in); void toJacobianBytesBE(const std::span out, const bool raw = false) const; void toJacobianBytesLE(const std::span out, const bool raw = false) const; diff --git a/src/fp.cpp b/src/fp.cpp index 4379033..8b0d3a5 100644 --- a/src/fp.cpp +++ b/src/fp.cpp @@ -17,21 +17,21 @@ fp::fp(const fp& e) : d{e.d[0], e.d[1], e.d[2], e.d[3], e.d[4], e.d[5]} { } -optional fp::fromBytesBE(const span in, const bool check, const bool raw) +optional fp::fromBytesBE(const span in, const conv_opt opt) { // We decided to always validate the input here. But we reserve the flag. fp e = fp(scalar::fromBytesBE<6>(in)); - if(check && !e.isValid()) return {}; - if(raw) return e; + if(opt.check && !e.isValid()) return {}; + if(opt.raw) return e; else return e.toMont(); } -optional fp::fromBytesLE(const span in, const bool check, const bool raw) +optional fp::fromBytesLE(const span in, const conv_opt opt) { // We decided to always validate the input here. But we reserve the flag. fp e = fp(scalar::fromBytesLE<6>(in)); - if(check && !e.isValid()) return {}; - if(raw) return e; + if(opt.check && !e.isValid()) return {}; + if(opt.raw) return e; else return e.toMont(); } @@ -465,18 +465,18 @@ fp2::fp2(const fp2& e) : c0(e.c0), c1(e.c1) { } -optional fp2::fromBytesBE(const span in, const bool check, const bool raw) +optional fp2::fromBytesBE(const span in, const conv_opt opt) { - optional c1 = fp::fromBytesBE(span(&in[ 0], &in[48]), check, raw); - optional c0 = fp::fromBytesBE(span(&in[48], &in[96]), check, raw); + optional c1 = fp::fromBytesBE(span(&in[ 0], &in[48]), opt); + optional c0 = fp::fromBytesBE(span(&in[48], &in[96]), opt); if(!c1 || !c0) return {}; return fp2({*c0, *c1}); } -optional fp2::fromBytesLE(const span in, const bool check, const bool raw) +optional fp2::fromBytesLE(const span in, const conv_opt opt) { - optional c0 = fp::fromBytesLE(span(&in[ 0], &in[48]), check, raw); - optional c1 = fp::fromBytesLE(span(&in[48], &in[96]), check, raw); + optional c0 = fp::fromBytesLE(span(&in[ 0], &in[48]), opt); + optional c1 = fp::fromBytesLE(span(&in[48], &in[96]), opt); if(!c1 || !c0) return {}; return fp2({*c0, *c1}); } @@ -825,20 +825,20 @@ fp6::fp6(const fp6& e) : c0(e.c0), c1(e.c1), c2(e.c2) { } -optional fp6::fromBytesBE(const span in, const bool check, const bool raw) +optional fp6::fromBytesBE(const span in, const conv_opt opt) { - optional c2 = fp2::fromBytesBE(span(&in[ 0], &in[ 96]), check, raw); - optional c1 = fp2::fromBytesBE(span(&in[ 96], &in[192]), check, raw); - optional c0 = fp2::fromBytesBE(span(&in[192], &in[288]), check, raw); + optional c2 = fp2::fromBytesBE(span(&in[ 0], &in[ 96]), opt); + optional c1 = fp2::fromBytesBE(span(&in[ 96], &in[192]), opt); + optional c0 = fp2::fromBytesBE(span(&in[192], &in[288]), opt); if(!c2 || !c1 || !c0) return {}; return fp6({*c0, *c1, *c2}); } -optional fp6::fromBytesLE(const span in, const bool check, const bool raw) +optional fp6::fromBytesLE(const span in, const conv_opt opt) { - optional c0 = fp2::fromBytesLE(span(&in[ 0], &in[ 96]), check, raw); - optional c1 = fp2::fromBytesLE(span(&in[ 96], &in[192]), check, raw); - optional c2 = fp2::fromBytesLE(span(&in[192], &in[288]), check, raw); + optional c0 = fp2::fromBytesLE(span(&in[ 0], &in[ 96]), opt); + optional c1 = fp2::fromBytesLE(span(&in[ 96], &in[192]), opt); + optional c2 = fp2::fromBytesLE(span(&in[192], &in[288]), opt); if(!c2 || !c1 || !c0) return {}; return fp6({*c0, *c1, *c2}); } @@ -1238,18 +1238,18 @@ fp12::fp12(const fp12& e) : c0(e.c0), c1(e.c1) { } -optional fp12::fromBytesBE(const span in, const bool check, const bool raw) +optional fp12::fromBytesBE(const span in, const conv_opt opt) { - optional c1 = fp6::fromBytesBE(span(&in[ 0], &in[288]), check, raw); - optional c0 = fp6::fromBytesBE(span(&in[288], &in[576]), check, raw); + optional c1 = fp6::fromBytesBE(span(&in[ 0], &in[288]), opt); + optional c0 = fp6::fromBytesBE(span(&in[288], &in[576]), opt); if(!c1 || !c0) return {}; return fp12({*c0, *c1}); } -optional fp12::fromBytesLE(const span in, const bool check, const bool raw) +optional fp12::fromBytesLE(const span in, const conv_opt opt) { - optional c0 = fp6::fromBytesLE(span(&in[ 0], &in[288]), check, raw); - optional c1 = fp6::fromBytesLE(span(&in[288], &in[576]), check, raw); + optional c0 = fp6::fromBytesLE(span(&in[ 0], &in[288]), opt); + optional c1 = fp6::fromBytesLE(span(&in[288], &in[576]), opt); if(!c1 || !c0) return {}; return fp12({*c0, *c1}); } diff --git a/src/g.cpp b/src/g.cpp index 6aac590..d1d9ada 100644 --- a/src/g.cpp +++ b/src/g.cpp @@ -17,41 +17,44 @@ g1::g1(const g1& e) : x(e.x), y(e.y), z(e.z) { } -optional g1::fromJacobianBytesBE(const span in, const bool check, const bool raw) +optional g1::fromJacobianBytesBE(const span in, conv_opt opt) { // We decided to always validate the input here. Check flag will only affect on-curve checks. - optional x = fp::fromBytesBE(span(&in[ 0], &in[ 48]), true, raw); - optional y = fp::fromBytesBE(span(&in[48], &in[ 96]), true, raw); - optional z = fp::fromBytesBE(span(&in[96], &in[144]), true, raw); + opt.check = true; + optional x = fp::fromBytesBE(span(&in[ 0], &in[ 48]), opt); + optional y = fp::fromBytesBE(span(&in[48], &in[ 96]), opt); + optional z = fp::fromBytesBE(span(&in[96], &in[144]), opt); if(!x || !y || !z) return {}; g1 p = g1({*x, *y, *z}); - if(check && !p.isOnCurve()) + if(opt.check && !p.isOnCurve()) { return {}; } return p; } -optional g1::fromJacobianBytesLE(const span in, const bool check, const bool raw) +optional g1::fromJacobianBytesLE(const span in, conv_opt opt) { // We decided to always validate the input here. Check flag will only affect on-curve checks. - optional x = fp::fromBytesLE(span(&in[ 0], &in[ 48]), true, raw); - optional y = fp::fromBytesLE(span(&in[48], &in[ 96]), true, raw); - optional z = fp::fromBytesLE(span(&in[96], &in[144]), true, raw); + opt.check = true; + optional x = fp::fromBytesLE(span(&in[ 0], &in[ 48]), opt); + optional y = fp::fromBytesLE(span(&in[48], &in[ 96]), opt); + optional z = fp::fromBytesLE(span(&in[96], &in[144]), opt); if(!x || !y || !z) return {}; g1 p = g1({*x, *y, *z}); - if(check && !p.isOnCurve()) + if(opt.check && !p.isOnCurve()) { return {}; } return p; } -optional g1::fromAffineBytesBE(const span in, const bool check, const bool raw) +optional g1::fromAffineBytesBE(const span in, conv_opt opt) { // We decided to always validate the input here. Check flag will only affect on-curve checks. - optional x = fp::fromBytesBE(span(&in[ 0], &in[ 48]), true, raw); - optional y = fp::fromBytesBE(span(&in[48], &in[ 96]), true, raw); + opt.check = true; + optional x = fp::fromBytesBE(span(&in[ 0], &in[ 48]), opt); + optional y = fp::fromBytesBE(span(&in[48], &in[ 96]), opt); if(!x || !y) return {}; // check if given input points to infinity if(x->isZero() && y->isZero()) @@ -60,18 +63,19 @@ optional g1::fromAffineBytesBE(const span in, const bool } fp z = fp::one(); g1 p = g1({*x, *y, z}); - if(check && !p.isOnCurve()) + if(opt.check && !p.isOnCurve()) { return {}; } return p; } -optional g1::fromAffineBytesLE(const span in, const bool check, const bool raw) +optional g1::fromAffineBytesLE(const span in, conv_opt opt) { // We decided to always validate the input here. Check flag will only affect on-curve checks. - optional x = fp::fromBytesLE(span(&in[ 0], &in[ 48]), true, raw); - optional y = fp::fromBytesLE(span(&in[48], &in[ 96]), true, raw); + opt.check = true; + optional x = fp::fromBytesLE(span(&in[ 0], &in[ 48]), opt); + optional y = fp::fromBytesLE(span(&in[48], &in[ 96]), opt); if(!x || !y) return {}; // check if given input points to infinity if(x->isZero() && y->isZero()) @@ -80,7 +84,7 @@ optional g1::fromAffineBytesLE(const span in, const bool } fp z = fp::one(); g1 p = g1({*x, *y, z}); - if(check && !p.isOnCurve()) + if(opt.check && !p.isOnCurve()) { return {}; } @@ -722,41 +726,44 @@ g2::g2(const g2& e) : x(e.x), y(e.y), z(e.z) { } -optional g2::fromJacobianBytesBE(const span in, const bool check, const bool raw) +optional g2::fromJacobianBytesBE(const span in, conv_opt opt) { // We decided to always validate the input here. Check flag will only affect on-curve checks. - optional x = fp2::fromBytesBE(span(&in[ 0], &in[ 96]), true, raw); - optional y = fp2::fromBytesBE(span(&in[ 96], &in[192]), true, raw); - optional z = fp2::fromBytesBE(span(&in[192], &in[288]), true, raw); + opt.check = true; + optional x = fp2::fromBytesBE(span(&in[ 0], &in[ 96]), opt); + optional y = fp2::fromBytesBE(span(&in[ 96], &in[192]), opt); + optional z = fp2::fromBytesBE(span(&in[192], &in[288]), opt); if(!x || !y || !z) return {}; g2 p = g2({*x, *y, *z}); - if(check && !p.isOnCurve()) + if(opt.check && !p.isOnCurve()) { return {}; } return p; } -optional g2::fromJacobianBytesLE(const span in, const bool check, const bool raw) +optional g2::fromJacobianBytesLE(const span in, conv_opt opt) { // We decided to always validate the input here. Check flag will only affect on-curve checks. - optional x = fp2::fromBytesLE(span(&in[ 0], &in[ 96]), true, raw); - optional y = fp2::fromBytesLE(span(&in[ 96], &in[192]), true, raw); - optional z = fp2::fromBytesLE(span(&in[192], &in[288]), true, raw); + opt.check = true; + optional x = fp2::fromBytesLE(span(&in[ 0], &in[ 96]), opt); + optional y = fp2::fromBytesLE(span(&in[ 96], &in[192]), opt); + optional z = fp2::fromBytesLE(span(&in[192], &in[288]), opt); if(!x || !y || !z) return {}; g2 p = g2({*x, *y, *z}); - if(check && !p.isOnCurve()) + if(opt.check && !p.isOnCurve()) { return {}; } return p; } -optional g2::fromAffineBytesBE(const span in, const bool check, const bool raw) +optional g2::fromAffineBytesBE(const span in, conv_opt opt) { // We decided to always validate the input here. Check flag will only affect on-curve checks. - optional x = fp2::fromBytesBE(span(&in[ 0], &in[ 96]), true, raw); - optional y = fp2::fromBytesBE(span(&in[ 96], &in[192]), true, raw); + opt.check = true; + optional x = fp2::fromBytesBE(span(&in[ 0], &in[ 96]), opt); + optional y = fp2::fromBytesBE(span(&in[ 96], &in[192]), opt); if(!x || !y) return {}; // check if given input points to infinity if(x->isZero() && y->isZero()) @@ -765,18 +772,19 @@ optional g2::fromAffineBytesBE(const span in, const bool } fp2 z = fp2::one(); g2 p = g2({*x, *y, z}); - if(check && !p.isOnCurve()) + if(opt.check && !p.isOnCurve()) { return {}; } return p; } -optional g2::fromAffineBytesLE(const span in, const bool check, const bool raw) +optional g2::fromAffineBytesLE(const span in, conv_opt opt) { // We decided to always validate the input here. Check flag will only affect on-curve checks. - optional x = fp2::fromBytesLE(span(&in[ 0], &in[ 96]), true, raw); - optional y = fp2::fromBytesLE(span(&in[ 96], &in[192]), true, raw); + opt.check = true; + optional x = fp2::fromBytesLE(span(&in[ 0], &in[ 96]), opt); + optional y = fp2::fromBytesLE(span(&in[ 96], &in[192]), opt); if(!x || !y) return {}; // check if given input points to infinity if(x->isZero() && y->isZero()) @@ -785,7 +793,7 @@ optional g2::fromAffineBytesLE(const span in, const bool } fp2 z = fp2::one(); g2 p = g2({*x, *y, z}); - if(check && !p.isOnCurve()) + if(opt.check && !p.isOnCurve()) { return {}; } diff --git a/test/unittests.cpp b/test/unittests.cpp index d9738e6..056b0e8 100644 --- a/test/unittests.cpp +++ b/test/unittests.cpp @@ -231,7 +231,7 @@ void TestFieldElementArithmeticCornerCases() { auto testSqureMul = [](const char* in, const char* expectedSquare, const char* expectedAdd) { // Input should be convert to Montgomery form, so "raw" = false - auto input = fp::fromBytesBE(hexToBytes<48>(in), true, false); + auto input = fp::fromBytesBE(hexToBytes<48>(in), { .check = true, .raw = false }); if (0 == strcmp("NA", expectedSquare)) { if (input) { @@ -241,8 +241,8 @@ void TestFieldElementArithmeticCornerCases() { } // Expected result will be compared against numbers converted back from Montgomery form, so "raw" = true - auto fpExpectedSquare = fp::fromBytesBE(hexToBytes<48>(expectedSquare), false, true); - auto fpExpectedAdd = fp::fromBytesBE(hexToBytes<48>(expectedAdd), false, true); + auto fpExpectedSquare = fp::fromBytesBE(hexToBytes<48>(expectedSquare), { .check=false, .raw=true }); + auto fpExpectedAdd = fp::fromBytesBE(hexToBytes<48>(expectedAdd), { .check = false, .raw = true }); fp s,m,a,d; fp s1,m1,a1,d1; @@ -437,7 +437,7 @@ void TestInverse() { throw invalid_argument("2 * 2^-1 != 1"); } - auto pminus1 = *fp::fromBytesBE(hexToBytes<48>("1A0111EA397FE69A4B1BA7B6434BACD764774B84F38512BF6730D2A0F6B0F6241EABFFFEB153FFFFB9FEFFFFFFFFAAAA"), false, true); + auto pminus1 = *fp::fromBytesBE(hexToBytes<48>("1A0111EA397FE69A4B1BA7B6434BACD764774B84F38512BF6730D2A0F6B0F6241EABFFFEB153FFFFB9FEFFFFFFFFAAAA"), { .check = false, .raw = true }); if (!pminus1.multiply(pminus1.inverse()).equal(fp::one())) { throw invalid_argument("(p-1) * (p-1)^-1 != 1"); } @@ -497,7 +497,7 @@ void TestMod() { auto s = hexToBytes<64>(testVectorInput[i]); auto k = scalar::fromBytesBE<8>(s); fp r = fp::modPrime<8>(k); - auto fpExpected = fp::fromBytesBE(hexToBytes<48>(testVectorExpected[i]), false, false); + auto fpExpected = fp::fromBytesBE(hexToBytes<48>(testVectorExpected[i]), { .check = false, .raw = false }); if(!fpExpected->equal(r)) { throw invalid_argument("r != expected for Mod"); @@ -531,10 +531,10 @@ void TestExp() { for (size_t i = 0; i < sizeof(testVectorInput)/sizeof(const char*); ++ i) { auto s = hexToBytes<64>(testVectorInput[i]); - auto b = fp::fromBytesBE(hexToBytes<48>(testVectorInput2[i]), false, false); + auto b = fp::fromBytesBE(hexToBytes<48>(testVectorInput2[i]), { .check = false, .raw = false }); auto k = scalar::fromBytesBE<8>(s); fp r = b->exp(k); - auto fpExpected = fp::fromBytesBE(hexToBytes<48>(testVectorExpected[i]), false, false); + auto fpExpected = fp::fromBytesBE(hexToBytes<48>(testVectorExpected[i]), { .check = false, .raw = false }); if(!fpExpected->equal(r)) { throw invalid_argument("r != expected for Exp"); @@ -750,12 +750,12 @@ void TestG1SerializationGarbage() { array buf; buf.fill(0xff); for (int i = 0 ; i < 4; ++i ) { - auto a = g1::fromJacobianBytesBE(buf, i < 2, i%2); + auto a = g1::fromJacobianBytesBE(buf, { .check = i<2, .raw = !!(i%2) }); if(a) { throw invalid_argument("g1, jacobianBE: serialization not catching invalid input"); } - auto b = g1::fromJacobianBytesLE(buf, i < 2, i%2); + auto b = g1::fromJacobianBytesLE(buf, { .check = i<2, .raw = !!(i%2) }); if(b) { throw invalid_argument("g1, jacobianLE: serialization not catching invalid input"); @@ -763,12 +763,12 @@ void TestG1SerializationGarbage() { } for (int i = 0 ; i < 4; ++i ) { - auto a = g1::fromAffineBytesBE(std::span{buf.begin(),96}, i < 2, i%2); + auto a = g1::fromAffineBytesBE(std::span{buf.begin(),96}, { .check = i<2, .raw = !!(i%2) }); if(a) { throw invalid_argument("g1, affineBE: serialization not catching invalid input"); } - auto b = g1::fromAffineBytesLE(std::span{buf.begin(),96}, i < 2, i%2); + auto b = g1::fromAffineBytesLE(std::span{buf.begin(),96}, { .check = i<2, .raw = !!(i%2) }); if(b) { throw invalid_argument("g1, affineLE: serialization not catching invalid input"); @@ -1138,24 +1138,24 @@ void TestG2SerializationGarbage() { array buf; buf.fill(0xff); for (int i = 0 ; i < 4; ++i ) { - auto a = g2::fromJacobianBytesBE(buf, i < 2, i%2); + auto a = g2::fromJacobianBytesBE(buf, { .check = i<2, .raw = !!(i%2) }); if(a) { throw invalid_argument("g2, jacobianBE: serialization not catching invalid input"); } - auto b = g2::fromJacobianBytesLE(buf, i < 2, i%2); + auto b = g2::fromJacobianBytesLE(buf, { .check = i<2, .raw = !!(i%2) }); if(b) { throw invalid_argument("g2, jacobianLE: serialization not catching invalid input"); } } for (int i = 0 ; i < 4; ++i ) { - auto a = g2::fromAffineBytesBE(std::span{buf.begin(),192}, i < 2, i%2); + auto a = g2::fromAffineBytesBE(std::span{buf.begin(),192}, { .check = i<2, .raw = !!(i%2) }); if(a) { throw invalid_argument("g2, affineBE: serialization not catching invalid input"); } - auto b = g2::fromAffineBytesLE(std::span{buf.begin(),192}, i < 2, i%2); + auto b = g2::fromAffineBytesLE(std::span{buf.begin(),192}, { .check = i<2, .raw = !!(i%2) }); if(b) { throw invalid_argument("g2, affineLE: serialization not catching invalid input"); @@ -2227,10 +2227,10 @@ void TestOutOfRangeInputs() { // This test is to make sure multiplication wiil not fail if the inputs is just slightly larger than p // The 4(p-1) limit may be not that strict. But we should only relax this limit if we are absolutely sure this // will not cause problems all the methods calling _ladd/_lsubstract/_ldouble. - auto p = *fp::fromBytesBE(hexToBytes<48>("1A0111EA397FE69A4B1BA7B6434BACD764774B84F38512BF6730D2A0F6B0F6241EABFFFEB153FFFFB9FEFFFFFFFFAAAB"), false, true); - auto pminus1 = *fp::fromBytesBE(hexToBytes<48>("1A0111EA397FE69A4B1BA7B6434BACD764774B84F38512BF6730D2A0F6B0F6241EABFFFEB153FFFFB9FEFFFFFFFFAAAA"), false, true); + auto p = *fp::fromBytesBE(hexToBytes<48>("1A0111EA397FE69A4B1BA7B6434BACD764774B84F38512BF6730D2A0F6B0F6241EABFFFEB153FFFFB9FEFFFFFFFFAAAB"), { .check = false, .raw = true }); + auto pminus1 = *fp::fromBytesBE(hexToBytes<48>("1A0111EA397FE69A4B1BA7B6434BACD764774B84F38512BF6730D2A0F6B0F6241EABFFFEB153FFFFB9FEFFFFFFFFAAAA"), { .check = false, .raw = true }); // 2^383, largest possible input to multiplication during the inverse(). - auto two383 = *fp::fromBytesBE(hexToBytes<48>("400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"), false, true); + auto two383 = *fp::fromBytesBE(hexToBytes<48>("400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"), { .check = false, .raw = true }); // 4(p-1) * 4(p-1) will work for (int i = 0 ; i < 3; ++ i) { auto a = pminus1; From 8f12ae4fc8dd14d4368238f9f0501d63ea60f503 Mon Sep 17 00:00:00 2001 From: greg7mdp Date: Mon, 1 Apr 2024 18:41:08 -0400 Subject: [PATCH 2/8] Rename options for to/from bytes. --- bench/eth_bench.cpp | 28 ++++----- include/bls12-381/fp.hpp | 56 +++++++++--------- include/bls12-381/g.hpp | 48 ++++++++-------- src/fp.cpp | 100 ++++++++++++++++---------------- src/g.cpp | 120 +++++++++++++++++++-------------------- src/signatures.cpp | 4 +- test/unittests.cpp | 36 ++++++------ 7 files changed, 197 insertions(+), 195 deletions(-) diff --git a/bench/eth_bench.cpp b/bench/eth_bench.cpp index 282046e..7368b32 100644 --- a/bench/eth_bench.cpp +++ b/bench/eth_bench.cpp @@ -206,22 +206,22 @@ void benchG1Add2() { auto performTest = [pbak](conv_opt opt) { array pRaw = {}; g1 p = pbak; - p.toJacobianBytesLE(pRaw, opt.raw); + p.toJacobianBytesLE(pRaw, opt.to_mont ? from_mont::yes : from_mont::no); auto start = startStopwatch(); for (int i = 0; i < numIters; i++) { p = *g1::fromJacobianBytesLE(pRaw, opt); p.addAssign(p); - p.toJacobianBytesLE(pRaw, opt.raw); + p.toJacobianBytesLE(pRaw, opt.to_mont ? from_mont::yes : from_mont::no); } - endStopwatch(string("check=") + std::to_string(opt.check) + string(", raw=") + std::to_string(opt.raw), start, numIters); + endStopwatch(string("check=") + std::to_string(opt.check_valid) + string(", raw=") + std::to_string(opt.to_mont), start, numIters); }; - performTest({ .check = true, .raw = true }); - performTest({ .check = true, .raw = false }); - performTest({ .check = false, .raw = true }); - performTest({ .check = false, .raw = false }); + performTest({ .check_valid = true, .to_mont = true }); + performTest({ .check_valid = true, .to_mont = false }); + performTest({ .check_valid = false, .to_mont = true }); + performTest({ .check_valid = false, .to_mont = false }); } @@ -235,22 +235,22 @@ void benchG2Add2() { auto performTest = [pbak](conv_opt opt) { array pRaw = {}; g2 p = pbak; - p.toJacobianBytesLE(pRaw, opt.raw); + p.toJacobianBytesLE(pRaw, opt.to_mont ? from_mont::yes : from_mont::no); auto start = startStopwatch(); for (int i = 0; i < numIters; i++) { p = *g2::fromJacobianBytesLE(pRaw, opt); p.addAssign(p); - p.toJacobianBytesLE(pRaw, opt.raw); + p.toJacobianBytesLE(pRaw, opt.to_mont ? from_mont::yes : from_mont::no); } - endStopwatch(string("check=") + std::to_string(opt.check) + string(", raw=") + std::to_string(opt.raw), start, numIters); + endStopwatch(string("check=") + std::to_string(opt.check_valid) + string(", raw=") + std::to_string(opt.to_mont), start, numIters); }; - performTest({ .check = true, .raw = true }); - performTest({ .check = true, .raw = false }); - performTest({ .check = false, .raw = true }); - performTest({ .check = false, .raw = false }); + performTest({ .check_valid = true, .to_mont = true }); + performTest({ .check_valid = true, .to_mont = false }); + performTest({ .check_valid = false, .to_mont = true }); + performTest({ .check_valid = false, .to_mont = false }); } diff --git a/include/bls12-381/fp.hpp b/include/bls12-381/fp.hpp index da2bb4c..32fd84f 100644 --- a/include/bls12-381/fp.hpp +++ b/include/bls12-381/fp.hpp @@ -12,10 +12,12 @@ namespace bls12_381 { struct conv_opt { - bool check; - bool raw; // no conversion to/from montgomery form + bool check_valid; // check bytes hold a valid encoding + bool to_mont; // convert to montgomery form }; +enum class from_mont : uint8_t { no = 0, yes }; + // element representation of 'fp' field which is the base field class fp { @@ -27,13 +29,13 @@ class fp explicit fp(const std::array& d); fp(const fp& e); static std::optional fromBytesBE(const std::span in, - const conv_opt opt = { .check = true, .raw = false }); + const conv_opt opt = { .check_valid = true, .to_mont = true }); static std::optional fromBytesLE(const std::span in, - const conv_opt opt = { .check = true, .raw = false }); - void toBytesBE(const std::span out, const bool raw = false) const; - void toBytesLE(const std::span out, const bool raw = false) const; - std::array toBytesBE(const bool raw = false) const; - std::array toBytesLE(const bool raw = false) const; + const conv_opt opt = { .check_valid = true, .to_mont = true }); + void toBytesBE(const std::span out, const from_mont fm = from_mont::yes) const; + void toBytesLE(const std::span out, const from_mont fm = from_mont::yes) const; + std::array toBytesBE(const from_mont fm = from_mont::yes) const; + std::array toBytesLE(const from_mont fm = from_mont::yes) const; static fp zero(); static fp one(); bool isValid() const; @@ -115,13 +117,13 @@ class fp2 explicit fp2(const std::array& e2); fp2(const fp2& e); static std::optional fromBytesBE(const std::span in, - const conv_opt opt = { .check = true, .raw = false }); + const conv_opt opt = { .check_valid = true, .to_mont = true }); static std::optional fromBytesLE(const std::span in, - const conv_opt opt = { .check = true, .raw = false }); - void toBytesBE(const std::span out, const bool raw = false) const; - void toBytesLE(const std::span out, const bool raw = false) const; - std::array toBytesBE(const bool raw = false) const; - std::array toBytesLE(const bool raw = false) const; + const conv_opt opt = { .check_valid = true, .to_mont = true }); + void toBytesBE(const std::span out, const from_mont fm = from_mont::yes) const; + void toBytesLE(const std::span out, const from_mont fm = from_mont::yes) const; + std::array toBytesBE(const from_mont fm = from_mont::yes) const; + std::array toBytesLE(const from_mont fm = from_mont::yes) const; static fp2 zero(); static fp2 one(); bool isZero() const; @@ -176,13 +178,13 @@ class fp6 explicit fp6(const std::array& e3); fp6(const fp6& e); static std::optional fromBytesBE(const std::span in, - const conv_opt opt = { .check = true, .raw = false }); + const conv_opt opt = { .check_valid = true, .to_mont = true }); static std::optional fromBytesLE(const std::span in, - const conv_opt opt = { .check = true, .raw = false }); - void toBytesBE(const std::span out, const bool raw = false) const; - void toBytesLE(const std::span out, const bool raw = false) const; - std::array toBytesBE(const bool raw = false) const; - std::array toBytesLE(const bool raw = false) const; + const conv_opt opt = { .check_valid = true, .to_mont = true }); + void toBytesBE(const std::span out, const from_mont fm = from_mont::yes) const; + void toBytesLE(const std::span out, const from_mont fm = from_mont::yes) const; + std::array toBytesBE(const from_mont fm = from_mont::yes) const; + std::array toBytesLE(const from_mont fm = from_mont::yes) const; static fp6 zero(); static fp6 one(); bool isZero() const; @@ -223,16 +225,16 @@ class fp12 fp6 c1; fp12(); - explicit fp12(const std::array& e2); + explicit fp12(const std::array& eG2); fp12(const fp12& e); static std::optional fromBytesBE(const std::span in, - const conv_opt opt = { .check = true, .raw = false }); + const conv_opt opt = { .check_valid = true, .to_mont = true }); static std::optional fromBytesLE(const std::span in, - const conv_opt opt = { .check = true, .raw = false }); - void toBytesBE(const std::span out, const bool raw = false) const; - void toBytesLE(const std::span out, const bool raw = false) const; - std::array toBytesBE(const bool raw = false) const; - std::array toBytesLE(const bool raw = false) const; + const conv_opt opt = { .check_valid = true, .to_mont = true }); + void toBytesBE(const std::span out, const from_mont fm = from_mont::yes) const; + void toBytesLE(const std::span out, const from_mont fm = from_mont::yes) const; + std::array toBytesBE(const from_mont fm = from_mont::yes) const; + std::array toBytesLE(const from_mont fm = from_mont::yes) const; static fp12 zero(); static fp12 one(); bool isZero() const; diff --git a/include/bls12-381/g.hpp b/include/bls12-381/g.hpp index 1bfb986..fdaa920 100644 --- a/include/bls12-381/g.hpp +++ b/include/bls12-381/g.hpp @@ -24,23 +24,23 @@ class g1 explicit g1(const std::array& e3); g1(const g1& e); static std::optional fromJacobianBytesBE(const std::span in, - conv_opt opt = { .check = false, .raw = false }); + conv_opt opt = { .check_valid = false, .to_mont = true }); static std::optional fromJacobianBytesLE(const std::span in, - conv_opt opt = { .check = false, .raw = false }); + conv_opt opt = { .check_valid = false, .to_mont = true }); static std::optional fromAffineBytesBE(const std::span in, - conv_opt opt = { .check = false, .raw = false }); + conv_opt opt = { .check_valid = false, .to_mont = true }); static std::optional fromAffineBytesLE(const std::span in, - conv_opt opt = { .check = false, .raw = false }); + conv_opt opt = { .check_valid = false, .to_mont = true }); static std::optional fromCompressedBytesBE(const std::span in); - void toJacobianBytesBE(const std::span out, const bool raw = false) const; - void toJacobianBytesLE(const std::span out, const bool raw = false) const; - void toAffineBytesBE(const std::span out, const bool raw = false) const; - void toAffineBytesLE(const std::span out, const bool raw = false) const; + void toJacobianBytesBE(const std::span out, const from_mont fm = from_mont::yes) const; + void toJacobianBytesLE(const std::span out, const from_mont fm = from_mont::yes) const; + void toAffineBytesBE(const std::span out, const from_mont fm = from_mont::yes) const; + void toAffineBytesLE(const std::span out, const from_mont fm = from_mont::yes) const; void toCompressedBytesBE(const std::span out) const; - std::array toJacobianBytesBE(const bool raw = false) const; - std::array toJacobianBytesLE(const bool raw = false) const; - std::array toAffineBytesBE(const bool raw = false) const; - std::array toAffineBytesLE(const bool raw = false) const; + std::array toJacobianBytesBE(const from_mont fm = from_mont::yes) const; + std::array toJacobianBytesLE(const from_mont fm = from_mont::yes) const; + std::array toAffineBytesBE(const from_mont fm = from_mont::yes) const; + std::array toAffineBytesLE(const from_mont fm = from_mont::yes) const; std::array toCompressedBytesBE() const; static g1 zero(); static g1 one(); @@ -90,23 +90,23 @@ class g2 explicit g2(const std::array& e3); g2(const g2& e); static std::optional fromJacobianBytesBE(const std::span in, - conv_opt opt = { .check = false, .raw = false }); + conv_opt opt = { .check_valid = false, .to_mont = true }); static std::optional fromJacobianBytesLE(const std::span in, - conv_opt opt = { .check = false, .raw = false }); + conv_opt opt = { .check_valid = false, .to_mont = true }); static std::optional fromAffineBytesBE(const std::span in, - conv_opt opt = { .check = false, .raw = false }); + conv_opt opt = { .check_valid = false, .to_mont = true }); static std::optional fromAffineBytesLE(const std::span in, - conv_opt opt = { .check = false, .raw = false }); + conv_opt opt = { .check_valid = false, .to_mont = true }); static std::optional fromCompressedBytesBE(const std::span in); - void toJacobianBytesBE(const std::span out, const bool raw = false) const; - void toJacobianBytesLE(const std::span out, const bool raw = false) const; - void toAffineBytesBE(const std::span out, const bool raw = false) const; - void toAffineBytesLE(const std::span out, const bool raw = false) const; + void toJacobianBytesBE(const std::span out, const from_mont fm = from_mont::yes) const; + void toJacobianBytesLE(const std::span out, const from_mont fm = from_mont::yes) const; + void toAffineBytesBE(const std::span out, const from_mont fm = from_mont::yes) const; + void toAffineBytesLE(const std::span out, const from_mont fm = from_mont::yes) const; void toCompressedBytesBE(const std::span out) const; - std::array toJacobianBytesBE(const bool raw = false) const; - std::array toJacobianBytesLE(const bool raw = false) const; - std::array toAffineBytesBE(const bool raw = false) const; - std::array toAffineBytesLE(const bool raw = false) const; + std::array toJacobianBytesBE(const from_mont fm = from_mont::yes) const; + std::array toJacobianBytesLE(const from_mont fm = from_mont::yes) const; + std::array toAffineBytesBE(const from_mont fm = from_mont::yes) const; + std::array toAffineBytesLE(const from_mont fm = from_mont::yes) const; std::array toCompressedBytesBE() const; static g2 zero(); static g2 one(); diff --git a/src/fp.cpp b/src/fp.cpp index 8b0d3a5..317dc74 100644 --- a/src/fp.cpp +++ b/src/fp.cpp @@ -21,42 +21,42 @@ optional fp::fromBytesBE(const span in, const conv_opt op { // We decided to always validate the input here. But we reserve the flag. fp e = fp(scalar::fromBytesBE<6>(in)); - if(opt.check && !e.isValid()) return {}; - if(opt.raw) return e; - else return e.toMont(); + if(opt.check_valid && !e.isValid()) return {}; + if(opt.to_mont) return e.toMont(); + else return e; } optional fp::fromBytesLE(const span in, const conv_opt opt) { // We decided to always validate the input here. But we reserve the flag. fp e = fp(scalar::fromBytesLE<6>(in)); - if(opt.check && !e.isValid()) return {}; - if(opt.raw) return e; - else return e.toMont(); + if(opt.check_valid && !e.isValid()) return {}; + if(opt.to_mont) return e.toMont(); + else return e; } -void fp::toBytesBE(const span out, const bool raw) const +void fp::toBytesBE(const span out, const from_mont fm /* = from_mont::yes */) const { - if(raw) scalar::toBytesBE<6>(d, out); - else scalar::toBytesBE<6>(fromMont().d, out); + if(fm == from_mont::no) scalar::toBytesBE<6>(d, out); + else scalar::toBytesBE<6>(fromMont().d, out); } -void fp::toBytesLE(const span out, const bool raw) const +void fp::toBytesLE(const span out, const from_mont fm /* = from_mont::yes */) const { - if(raw) scalar::toBytesLE<6>(d, out); - else scalar::toBytesLE<6>(fromMont().d, out); + if(fm == from_mont::no) scalar::toBytesLE<6>(d, out); + else scalar::toBytesLE<6>(fromMont().d, out); } -array fp::toBytesBE(const bool raw) const +array fp::toBytesBE(const from_mont fm /* = from_mont::yes */) const { - if(raw) return scalar::toBytesBE<6>(d); - else return scalar::toBytesBE<6>(fromMont().d); + if(fm == from_mont::no) return scalar::toBytesBE<6>(d); + else return scalar::toBytesBE<6>(fromMont().d); } -array fp::toBytesLE(const bool raw) const +array fp::toBytesLE(const from_mont fm /* = from_mont::yes */) const { - if(raw) return scalar::toBytesLE<6>(d); - else return scalar::toBytesLE<6>(fromMont().d); + if(fm == from_mont::no) return scalar::toBytesLE<6>(d); + else return scalar::toBytesLE<6>(fromMont().d); } fp fp::zero() @@ -481,29 +481,29 @@ optional fp2::fromBytesLE(const span in, const conv_opt return fp2({*c0, *c1}); } -void fp2::toBytesBE(const span out, const bool raw) const +void fp2::toBytesBE(const span out, const from_mont fm /* = from_mont::yes */) const { - memcpy(&out[ 0], &c1.toBytesBE(raw)[0], 48); - memcpy(&out[48], &c0.toBytesBE(raw)[0], 48); + memcpy(&out[ 0], &c1.toBytesBE(fm)[0], 48); + memcpy(&out[48], &c0.toBytesBE(fm)[0], 48); } -void fp2::toBytesLE(const span out, const bool raw) const +void fp2::toBytesLE(const span out, const from_mont fm /* = from_mont::yes */) const { - memcpy(&out[ 0], &c0.toBytesLE(raw)[0], 48); - memcpy(&out[48], &c1.toBytesLE(raw)[0], 48); + memcpy(&out[ 0], &c0.toBytesLE(fm)[0], 48); + memcpy(&out[48], &c1.toBytesLE(fm)[0], 48); } -array fp2::toBytesBE(const bool raw) const +array fp2::toBytesBE(const from_mont fm /* = from_mont::yes */) const { array out; - toBytesBE(out, raw); + toBytesBE(out, fm); return out; } -array fp2::toBytesLE(const bool raw) const +array fp2::toBytesLE(const from_mont fm /* = from_mont::yes */) const { array out; - toBytesLE(out, raw); + toBytesLE(out, fm); return out; } @@ -843,31 +843,31 @@ optional fp6::fromBytesLE(const span in, const conv_opt return fp6({*c0, *c1, *c2}); } -void fp6::toBytesBE(const span out, const bool raw) const +void fp6::toBytesBE(const span out, const from_mont fm /* = from_mont::yes */) const { - memcpy(&out[ 0], &c2.toBytesBE(raw)[0], 96); - memcpy(&out[ 96], &c1.toBytesBE(raw)[0], 96); - memcpy(&out[192], &c0.toBytesBE(raw)[0], 96); + memcpy(&out[ 0], &c2.toBytesBE(fm)[0], 96); + memcpy(&out[ 96], &c1.toBytesBE(fm)[0], 96); + memcpy(&out[192], &c0.toBytesBE(fm)[0], 96); } -void fp6::toBytesLE(const span out, const bool raw) const +void fp6::toBytesLE(const span out, const from_mont fm /* = from_mont::yes */) const { - memcpy(&out[ 0], &c0.toBytesLE(raw)[0], 96); - memcpy(&out[ 96], &c1.toBytesLE(raw)[0], 96); - memcpy(&out[192], &c2.toBytesLE(raw)[0], 96); + memcpy(&out[ 0], &c0.toBytesLE(fm)[0], 96); + memcpy(&out[ 96], &c1.toBytesLE(fm)[0], 96); + memcpy(&out[192], &c2.toBytesLE(fm)[0], 96); } -array fp6::toBytesBE(const bool raw) const +array fp6::toBytesBE(const from_mont fm /* = from_mont::yes */) const { array out; - toBytesBE(out, raw); + toBytesBE(out, fm); return out; } -array fp6::toBytesLE(const bool raw) const +array fp6::toBytesLE(const from_mont fm /* = from_mont::yes */) const { array out; - toBytesLE(out, raw); + toBytesLE(out, fm); return out; } @@ -1254,29 +1254,29 @@ optional fp12::fromBytesLE(const span in, const conv_o return fp12({*c0, *c1}); } -void fp12::toBytesBE(const span out, const bool raw) const +void fp12::toBytesBE(const span out, const from_mont fm /* = from_mont::yes */) const { - memcpy(&out[ 0], &c1.toBytesBE(raw)[0], 288); - memcpy(&out[288], &c0.toBytesBE(raw)[0], 288); + memcpy(&out[ 0], &c1.toBytesBE(fm)[0], 288); + memcpy(&out[288], &c0.toBytesBE(fm)[0], 288); } -void fp12::toBytesLE(const span out, const bool raw) const +void fp12::toBytesLE(const span out, const from_mont fm /* = from_mont::yes */) const { - memcpy(&out[ 0], &c0.toBytesLE(raw)[0], 288); - memcpy(&out[288], &c1.toBytesLE(raw)[0], 288); + memcpy(&out[ 0], &c0.toBytesLE(fm)[0], 288); + memcpy(&out[288], &c1.toBytesLE(fm)[0], 288); } -array fp12::toBytesBE(const bool raw) const +array fp12::toBytesBE(const from_mont fm /* = from_mont::yes */) const { array out; - toBytesBE(out, raw); + toBytesBE(out, fm); return out; } -array fp12::toBytesLE(const bool raw) const +array fp12::toBytesLE(const from_mont fm /* = from_mont::yes */) const { array out; - toBytesLE(out, raw); + toBytesLE(out, fm); return out; } diff --git a/src/g.cpp b/src/g.cpp index d1d9ada..c4c75d3 100644 --- a/src/g.cpp +++ b/src/g.cpp @@ -20,13 +20,13 @@ g1::g1(const g1& e) : x(e.x), y(e.y), z(e.z) optional g1::fromJacobianBytesBE(const span in, conv_opt opt) { // We decided to always validate the input here. Check flag will only affect on-curve checks. - opt.check = true; + opt.check_valid = true; optional x = fp::fromBytesBE(span(&in[ 0], &in[ 48]), opt); optional y = fp::fromBytesBE(span(&in[48], &in[ 96]), opt); optional z = fp::fromBytesBE(span(&in[96], &in[144]), opt); if(!x || !y || !z) return {}; g1 p = g1({*x, *y, *z}); - if(opt.check && !p.isOnCurve()) + if(opt.check_valid && !p.isOnCurve()) { return {}; } @@ -36,13 +36,13 @@ optional g1::fromJacobianBytesBE(const span in, conv_opt optional g1::fromJacobianBytesLE(const span in, conv_opt opt) { // We decided to always validate the input here. Check flag will only affect on-curve checks. - opt.check = true; + opt.check_valid = true; optional x = fp::fromBytesLE(span(&in[ 0], &in[ 48]), opt); optional y = fp::fromBytesLE(span(&in[48], &in[ 96]), opt); optional z = fp::fromBytesLE(span(&in[96], &in[144]), opt); if(!x || !y || !z) return {}; g1 p = g1({*x, *y, *z}); - if(opt.check && !p.isOnCurve()) + if(opt.check_valid && !p.isOnCurve()) { return {}; } @@ -52,7 +52,7 @@ optional g1::fromJacobianBytesLE(const span in, conv_opt optional g1::fromAffineBytesBE(const span in, conv_opt opt) { // We decided to always validate the input here. Check flag will only affect on-curve checks. - opt.check = true; + opt.check_valid = true; optional x = fp::fromBytesBE(span(&in[ 0], &in[ 48]), opt); optional y = fp::fromBytesBE(span(&in[48], &in[ 96]), opt); if(!x || !y) return {}; @@ -63,7 +63,7 @@ optional g1::fromAffineBytesBE(const span in, conv_opt op } fp z = fp::one(); g1 p = g1({*x, *y, z}); - if(opt.check && !p.isOnCurve()) + if(opt.check_valid && !p.isOnCurve()) { return {}; } @@ -73,7 +73,7 @@ optional g1::fromAffineBytesBE(const span in, conv_opt op optional g1::fromAffineBytesLE(const span in, conv_opt opt) { // We decided to always validate the input here. Check flag will only affect on-curve checks. - opt.check = true; + opt.check_valid = true; optional x = fp::fromBytesLE(span(&in[ 0], &in[ 48]), opt); optional y = fp::fromBytesLE(span(&in[48], &in[ 96]), opt); if(!x || !y) return {}; @@ -84,7 +84,7 @@ optional g1::fromAffineBytesLE(const span in, conv_opt op } fp z = fp::one(); g1 p = g1({*x, *y, z}); - if(opt.check && !p.isOnCurve()) + if(opt.check_valid && !p.isOnCurve()) { return {}; } @@ -133,21 +133,21 @@ optional g1::fromCompressedBytesBE(const span in) return p; } -void g1::toJacobianBytesBE(const span out, const bool raw) const +void g1::toJacobianBytesBE(const span out, const from_mont fm /* = from_mont::yes */) const { - memcpy(&out[ 0], &x.toBytesBE(raw)[0], 48); - memcpy(&out[48], &y.toBytesBE(raw)[0], 48); - memcpy(&out[96], &z.toBytesBE(raw)[0], 48); + memcpy(&out[ 0], &x.toBytesBE(fm)[0], 48); + memcpy(&out[48], &y.toBytesBE(fm)[0], 48); + memcpy(&out[96], &z.toBytesBE(fm)[0], 48); } -void g1::toJacobianBytesLE(const span out, const bool raw) const +void g1::toJacobianBytesLE(const span out, const from_mont fm /* = from_mont::yes */) const { - memcpy(&out[ 0], &x.toBytesLE(raw)[0], 48); - memcpy(&out[48], &y.toBytesLE(raw)[0], 48); - memcpy(&out[96], &z.toBytesLE(raw)[0], 48); + memcpy(&out[ 0], &x.toBytesLE(fm)[0], 48); + memcpy(&out[48], &y.toBytesLE(fm)[0], 48); + memcpy(&out[96], &z.toBytesLE(fm)[0], 48); } -void g1::toAffineBytesBE(const span out, const bool raw) const +void g1::toAffineBytesBE(const span out, const from_mont fm /* = from_mont::yes */) const { if(isZero()) { @@ -155,11 +155,11 @@ void g1::toAffineBytesBE(const span out, const bool raw) const return; } g1 r = affine(); - memcpy(&out[ 0], &r.x.toBytesBE(raw)[0], 48); - memcpy(&out[48], &r.y.toBytesBE(raw)[0], 48); + memcpy(&out[ 0], &r.x.toBytesBE(fm)[0], 48); + memcpy(&out[48], &r.y.toBytesBE(fm)[0], 48); } -void g1::toAffineBytesLE(const span out, const bool raw) const +void g1::toAffineBytesLE(const span out, const from_mont fm /* = from_mont::yes */) const { if(isZero()) { @@ -167,8 +167,8 @@ void g1::toAffineBytesLE(const span out, const bool raw) const return; } g1 r = affine(); - memcpy(&out[ 0], &r.x.toBytesLE(raw)[0], 48); - memcpy(&out[48], &r.y.toBytesLE(raw)[0], 48); + memcpy(&out[ 0], &r.x.toBytesLE(fm)[0], 48); + memcpy(&out[48], &r.y.toBytesLE(fm)[0], 48); } void g1::toCompressedBytesBE(const span out) const @@ -192,31 +192,31 @@ void g1::toCompressedBytesBE(const span out) const out[0] |= 0x80; } -array g1::toJacobianBytesBE(const bool raw) const +array g1::toJacobianBytesBE(const from_mont fm /* = from_mont::yes */) const { array out; - toJacobianBytesBE(out, raw); + toJacobianBytesBE(out, fm); return out; } -array g1::toJacobianBytesLE(const bool raw) const +array g1::toJacobianBytesLE(const from_mont fm /* = from_mont::yes */) const { array out; - toJacobianBytesLE(out, raw); + toJacobianBytesLE(out, fm); return out; } -array g1::toAffineBytesBE(const bool raw) const +array g1::toAffineBytesBE(const from_mont fm /* = from_mont::yes */) const { array out; - toAffineBytesBE(out, raw); + toAffineBytesBE(out, fm); return out; } -array g1::toAffineBytesLE(const bool raw) const +array g1::toAffineBytesLE(const from_mont fm /* = from_mont::yes */) const { array out; - toAffineBytesLE(out, raw); + toAffineBytesLE(out, fm); return out; } @@ -729,13 +729,13 @@ g2::g2(const g2& e) : x(e.x), y(e.y), z(e.z) optional g2::fromJacobianBytesBE(const span in, conv_opt opt) { // We decided to always validate the input here. Check flag will only affect on-curve checks. - opt.check = true; + opt.check_valid = true; optional x = fp2::fromBytesBE(span(&in[ 0], &in[ 96]), opt); optional y = fp2::fromBytesBE(span(&in[ 96], &in[192]), opt); optional z = fp2::fromBytesBE(span(&in[192], &in[288]), opt); if(!x || !y || !z) return {}; g2 p = g2({*x, *y, *z}); - if(opt.check && !p.isOnCurve()) + if(opt.check_valid && !p.isOnCurve()) { return {}; } @@ -745,13 +745,13 @@ optional g2::fromJacobianBytesBE(const span in, conv_opt optional g2::fromJacobianBytesLE(const span in, conv_opt opt) { // We decided to always validate the input here. Check flag will only affect on-curve checks. - opt.check = true; + opt.check_valid = true; optional x = fp2::fromBytesLE(span(&in[ 0], &in[ 96]), opt); optional y = fp2::fromBytesLE(span(&in[ 96], &in[192]), opt); optional z = fp2::fromBytesLE(span(&in[192], &in[288]), opt); if(!x || !y || !z) return {}; g2 p = g2({*x, *y, *z}); - if(opt.check && !p.isOnCurve()) + if(opt.check_valid && !p.isOnCurve()) { return {}; } @@ -761,7 +761,7 @@ optional g2::fromJacobianBytesLE(const span in, conv_opt optional g2::fromAffineBytesBE(const span in, conv_opt opt) { // We decided to always validate the input here. Check flag will only affect on-curve checks. - opt.check = true; + opt.check_valid = true; optional x = fp2::fromBytesBE(span(&in[ 0], &in[ 96]), opt); optional y = fp2::fromBytesBE(span(&in[ 96], &in[192]), opt); if(!x || !y) return {}; @@ -772,7 +772,7 @@ optional g2::fromAffineBytesBE(const span in, conv_opt o } fp2 z = fp2::one(); g2 p = g2({*x, *y, z}); - if(opt.check && !p.isOnCurve()) + if(opt.check_valid && !p.isOnCurve()) { return {}; } @@ -782,7 +782,7 @@ optional g2::fromAffineBytesBE(const span in, conv_opt o optional g2::fromAffineBytesLE(const span in, conv_opt opt) { // We decided to always validate the input here. Check flag will only affect on-curve checks. - opt.check = true; + opt.check_valid = true; optional x = fp2::fromBytesLE(span(&in[ 0], &in[ 96]), opt); optional y = fp2::fromBytesLE(span(&in[ 96], &in[192]), opt); if(!x || !y) return {}; @@ -793,7 +793,7 @@ optional g2::fromAffineBytesLE(const span in, conv_opt o } fp2 z = fp2::one(); g2 p = g2({*x, *y, z}); - if(opt.check && !p.isOnCurve()) + if(opt.check_valid && !p.isOnCurve()) { return {}; } @@ -847,21 +847,21 @@ optional g2::fromCompressedBytesBE(const span in) return p; } -void g2::toJacobianBytesBE(const span out, const bool raw) const +void g2::toJacobianBytesBE(const span out, const from_mont fm /* = from_mont::yes */) const { - memcpy(&out[ 0], &x.toBytesBE(raw)[0], 96); - memcpy(&out[ 96], &y.toBytesBE(raw)[0], 96); - memcpy(&out[192], &z.toBytesBE(raw)[0], 96); + memcpy(&out[ 0], &x.toBytesBE(fm)[0], 96); + memcpy(&out[ 96], &y.toBytesBE(fm)[0], 96); + memcpy(&out[192], &z.toBytesBE(fm)[0], 96); } -void g2::toJacobianBytesLE(const span out, const bool raw) const +void g2::toJacobianBytesLE(const span out, const from_mont fm /* = from_mont::yes */) const { - memcpy(&out[ 0], &x.toBytesLE(raw)[0], 96); - memcpy(&out[ 96], &y.toBytesLE(raw)[0], 96); - memcpy(&out[192], &z.toBytesLE(raw)[0], 96); + memcpy(&out[ 0], &x.toBytesLE(fm)[0], 96); + memcpy(&out[ 96], &y.toBytesLE(fm)[0], 96); + memcpy(&out[192], &z.toBytesLE(fm)[0], 96); } -void g2::toAffineBytesBE(const span out, const bool raw) const +void g2::toAffineBytesBE(const span out, const from_mont fm /* = from_mont::yes */) const { if(isZero()) { @@ -869,11 +869,11 @@ void g2::toAffineBytesBE(const span out, const bool raw) const return; } g2 r = affine(); - memcpy(&out[ 0], &r.x.toBytesBE(raw)[0], 96); - memcpy(&out[96], &r.y.toBytesBE(raw)[0], 96); + memcpy(&out[ 0], &r.x.toBytesBE(fm)[0], 96); + memcpy(&out[96], &r.y.toBytesBE(fm)[0], 96); } -void g2::toAffineBytesLE(const span out, const bool raw) const +void g2::toAffineBytesLE(const span out, const from_mont fm /* = from_mont::yes */) const { if(isZero()) { @@ -881,8 +881,8 @@ void g2::toAffineBytesLE(const span out, const bool raw) const return; } g2 r = affine(); - memcpy(&out[ 0], &r.x.toBytesLE(raw)[0], 96); - memcpy(&out[96], &r.y.toBytesLE(raw)[0], 96); + memcpy(&out[ 0], &r.x.toBytesLE(fm)[0], 96); + memcpy(&out[96], &r.y.toBytesLE(fm)[0], 96); } void g2::toCompressedBytesBE(const span out) const @@ -907,31 +907,31 @@ void g2::toCompressedBytesBE(const span out) const out[0] |= 0x80; } -array g2::toJacobianBytesBE(const bool raw) const +array g2::toJacobianBytesBE(const from_mont fm /* = from_mont::yes */) const { array out; - toJacobianBytesBE(out, raw); + toJacobianBytesBE(out, fm); return out; } -array g2::toJacobianBytesLE(const bool raw) const +array g2::toJacobianBytesLE(const from_mont fm /* = from_mont::yes */) const { array out; - toJacobianBytesLE(out, raw); + toJacobianBytesLE(out, fm); return out; } -array g2::toAffineBytesBE(const bool raw) const +array g2::toAffineBytesBE(const from_mont fm /* = from_mont::yes */) const { array out; - toAffineBytesBE(out, raw); + toAffineBytesBE(out, fm); return out; } -array g2::toAffineBytesLE(const bool raw) const +array g2::toAffineBytesLE(const from_mont fm /* = from_mont::yes */) const { array out; - toAffineBytesLE(out, raw); + toAffineBytesLE(out, fm); return out; } diff --git a/src/signatures.cpp b/src/signatures.cpp index 63b7f20..7dbc161 100644 --- a/src/signatures.cpp +++ b/src/signatures.cpp @@ -630,7 +630,7 @@ bool aggregate_verify( g2 pop_prove(const array& sk) { g1 pk = public_key(sk); - array msg = pk.toAffineBytesLE(false); + array msg = pk.toAffineBytesLE(from_mont::yes); g2 hashed_key = fromMessage(vector(msg.begin(), msg.end()), POP_CIPHERSUITE_ID); return hashed_key.scale(sk); } @@ -640,7 +640,7 @@ bool pop_verify( const g2& signature_proof ) { - array msg = pubkey.toAffineBytesLE(false); + array msg = pubkey.toAffineBytesLE(from_mont::yes); const g2 hashedPoint = fromMessage(vector(msg.begin(), msg.end()), POP_CIPHERSUITE_ID); if(!pubkey.isOnCurve() || !pubkey.inCorrectSubgroup()) diff --git a/test/unittests.cpp b/test/unittests.cpp index 056b0e8..422b087 100644 --- a/test/unittests.cpp +++ b/test/unittests.cpp @@ -231,7 +231,7 @@ void TestFieldElementArithmeticCornerCases() { auto testSqureMul = [](const char* in, const char* expectedSquare, const char* expectedAdd) { // Input should be convert to Montgomery form, so "raw" = false - auto input = fp::fromBytesBE(hexToBytes<48>(in), { .check = true, .raw = false }); + auto input = fp::fromBytesBE(hexToBytes<48>(in), { .check_valid = true, .to_mont = true }); if (0 == strcmp("NA", expectedSquare)) { if (input) { @@ -241,8 +241,8 @@ void TestFieldElementArithmeticCornerCases() { } // Expected result will be compared against numbers converted back from Montgomery form, so "raw" = true - auto fpExpectedSquare = fp::fromBytesBE(hexToBytes<48>(expectedSquare), { .check=false, .raw=true }); - auto fpExpectedAdd = fp::fromBytesBE(hexToBytes<48>(expectedAdd), { .check = false, .raw = true }); + auto fpExpectedSquare = fp::fromBytesBE(hexToBytes<48>(expectedSquare), { .check_valid=false, .to_mont=false }); + auto fpExpectedAdd = fp::fromBytesBE(hexToBytes<48>(expectedAdd), { .check_valid = false, .to_mont = false }); fp s,m,a,d; fp s1,m1,a1,d1; @@ -437,7 +437,7 @@ void TestInverse() { throw invalid_argument("2 * 2^-1 != 1"); } - auto pminus1 = *fp::fromBytesBE(hexToBytes<48>("1A0111EA397FE69A4B1BA7B6434BACD764774B84F38512BF6730D2A0F6B0F6241EABFFFEB153FFFFB9FEFFFFFFFFAAAA"), { .check = false, .raw = true }); + auto pminus1 = *fp::fromBytesBE(hexToBytes<48>("1A0111EA397FE69A4B1BA7B6434BACD764774B84F38512BF6730D2A0F6B0F6241EABFFFEB153FFFFB9FEFFFFFFFFAAAA"), { .check_valid = false, .to_mont = false }); if (!pminus1.multiply(pminus1.inverse()).equal(fp::one())) { throw invalid_argument("(p-1) * (p-1)^-1 != 1"); } @@ -497,7 +497,7 @@ void TestMod() { auto s = hexToBytes<64>(testVectorInput[i]); auto k = scalar::fromBytesBE<8>(s); fp r = fp::modPrime<8>(k); - auto fpExpected = fp::fromBytesBE(hexToBytes<48>(testVectorExpected[i]), { .check = false, .raw = false }); + auto fpExpected = fp::fromBytesBE(hexToBytes<48>(testVectorExpected[i]), { .check_valid = false, .to_mont = true }); if(!fpExpected->equal(r)) { throw invalid_argument("r != expected for Mod"); @@ -531,10 +531,10 @@ void TestExp() { for (size_t i = 0; i < sizeof(testVectorInput)/sizeof(const char*); ++ i) { auto s = hexToBytes<64>(testVectorInput[i]); - auto b = fp::fromBytesBE(hexToBytes<48>(testVectorInput2[i]), { .check = false, .raw = false }); + auto b = fp::fromBytesBE(hexToBytes<48>(testVectorInput2[i]), { .check_valid = false, .to_mont = true }); auto k = scalar::fromBytesBE<8>(s); fp r = b->exp(k); - auto fpExpected = fp::fromBytesBE(hexToBytes<48>(testVectorExpected[i]), { .check = false, .raw = false }); + auto fpExpected = fp::fromBytesBE(hexToBytes<48>(testVectorExpected[i]), { .check_valid = false, .to_mont = true }); if(!fpExpected->equal(r)) { throw invalid_argument("r != expected for Exp"); @@ -750,12 +750,12 @@ void TestG1SerializationGarbage() { array buf; buf.fill(0xff); for (int i = 0 ; i < 4; ++i ) { - auto a = g1::fromJacobianBytesBE(buf, { .check = i<2, .raw = !!(i%2) }); + auto a = g1::fromJacobianBytesBE(buf, { .check_valid = i<2, .to_mont = !(i%2) }); if(a) { throw invalid_argument("g1, jacobianBE: serialization not catching invalid input"); } - auto b = g1::fromJacobianBytesLE(buf, { .check = i<2, .raw = !!(i%2) }); + auto b = g1::fromJacobianBytesLE(buf, { .check_valid = i<2, .to_mont = !(i%2) }); if(b) { throw invalid_argument("g1, jacobianLE: serialization not catching invalid input"); @@ -763,12 +763,12 @@ void TestG1SerializationGarbage() { } for (int i = 0 ; i < 4; ++i ) { - auto a = g1::fromAffineBytesBE(std::span{buf.begin(),96}, { .check = i<2, .raw = !!(i%2) }); + auto a = g1::fromAffineBytesBE(std::span{buf.begin(),96}, { .check_valid = i<2, .to_mont = !(i%2) }); if(a) { throw invalid_argument("g1, affineBE: serialization not catching invalid input"); } - auto b = g1::fromAffineBytesLE(std::span{buf.begin(),96}, { .check = i<2, .raw = !!(i%2) }); + auto b = g1::fromAffineBytesLE(std::span{buf.begin(),96}, { .check_valid = i<2, .to_mont = !(i%2) }); if(b) { throw invalid_argument("g1, affineLE: serialization not catching invalid input"); @@ -1138,24 +1138,24 @@ void TestG2SerializationGarbage() { array buf; buf.fill(0xff); for (int i = 0 ; i < 4; ++i ) { - auto a = g2::fromJacobianBytesBE(buf, { .check = i<2, .raw = !!(i%2) }); + auto a = g2::fromJacobianBytesBE(buf, { .check_valid = i<2, .to_mont = !(i%2) }); if(a) { throw invalid_argument("g2, jacobianBE: serialization not catching invalid input"); } - auto b = g2::fromJacobianBytesLE(buf, { .check = i<2, .raw = !!(i%2) }); + auto b = g2::fromJacobianBytesLE(buf, { .check_valid = i<2, .to_mont = !(i%2) }); if(b) { throw invalid_argument("g2, jacobianLE: serialization not catching invalid input"); } } for (int i = 0 ; i < 4; ++i ) { - auto a = g2::fromAffineBytesBE(std::span{buf.begin(),192}, { .check = i<2, .raw = !!(i%2) }); + auto a = g2::fromAffineBytesBE(std::span{buf.begin(),192}, { .check_valid = i<2, .to_mont = !(i%2) }); if(a) { throw invalid_argument("g2, affineBE: serialization not catching invalid input"); } - auto b = g2::fromAffineBytesLE(std::span{buf.begin(),192}, { .check = i<2, .raw = !!(i%2) }); + auto b = g2::fromAffineBytesLE(std::span{buf.begin(),192}, { .check_valid = i<2, .to_mont = !(i%2) }); if(b) { throw invalid_argument("g2, affineLE: serialization not catching invalid input"); @@ -2227,10 +2227,10 @@ void TestOutOfRangeInputs() { // This test is to make sure multiplication wiil not fail if the inputs is just slightly larger than p // The 4(p-1) limit may be not that strict. But we should only relax this limit if we are absolutely sure this // will not cause problems all the methods calling _ladd/_lsubstract/_ldouble. - auto p = *fp::fromBytesBE(hexToBytes<48>("1A0111EA397FE69A4B1BA7B6434BACD764774B84F38512BF6730D2A0F6B0F6241EABFFFEB153FFFFB9FEFFFFFFFFAAAB"), { .check = false, .raw = true }); - auto pminus1 = *fp::fromBytesBE(hexToBytes<48>("1A0111EA397FE69A4B1BA7B6434BACD764774B84F38512BF6730D2A0F6B0F6241EABFFFEB153FFFFB9FEFFFFFFFFAAAA"), { .check = false, .raw = true }); + auto p = *fp::fromBytesBE(hexToBytes<48>("1A0111EA397FE69A4B1BA7B6434BACD764774B84F38512BF6730D2A0F6B0F6241EABFFFEB153FFFFB9FEFFFFFFFFAAAB"), { .check_valid = false, .to_mont = false }); + auto pminus1 = *fp::fromBytesBE(hexToBytes<48>("1A0111EA397FE69A4B1BA7B6434BACD764774B84F38512BF6730D2A0F6B0F6241EABFFFEB153FFFFB9FEFFFFFFFFAAAA"), { .check_valid = false, .to_mont = false }); // 2^383, largest possible input to multiplication during the inverse(). - auto two383 = *fp::fromBytesBE(hexToBytes<48>("400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"), { .check = false, .raw = true }); + auto two383 = *fp::fromBytesBE(hexToBytes<48>("400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"), { .check_valid = false, .to_mont = false }); // 4(p-1) * 4(p-1) will work for (int i = 0 ; i < 3; ++ i) { auto a = pminus1; From 030dcb6adef7fe5454c4a0986e682f4890edfa26 Mon Sep 17 00:00:00 2001 From: greg7mdp Date: Mon, 1 Apr 2024 18:47:51 -0400 Subject: [PATCH 3/8] Fix message text. --- bench/eth_bench.cpp | 4 ++-- include/bls12-381/fp.hpp | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/bench/eth_bench.cpp b/bench/eth_bench.cpp index 7368b32..2046460 100644 --- a/bench/eth_bench.cpp +++ b/bench/eth_bench.cpp @@ -215,7 +215,7 @@ void benchG1Add2() { p.addAssign(p); p.toJacobianBytesLE(pRaw, opt.to_mont ? from_mont::yes : from_mont::no); } - endStopwatch(string("check=") + std::to_string(opt.check_valid) + string(", raw=") + std::to_string(opt.to_mont), start, numIters); + endStopwatch(string("check_valid=") + std::to_string(opt.check_valid) + string(", to_mont=") + std::to_string(opt.to_mont), start, numIters); }; performTest({ .check_valid = true, .to_mont = true }); @@ -244,7 +244,7 @@ void benchG2Add2() { p.addAssign(p); p.toJacobianBytesLE(pRaw, opt.to_mont ? from_mont::yes : from_mont::no); } - endStopwatch(string("check=") + std::to_string(opt.check_valid) + string(", raw=") + std::to_string(opt.to_mont), start, numIters); + endStopwatch(string("check_valid=") + std::to_string(opt.check_valid) + string(", to_mont=") + std::to_string(opt.to_mont), start, numIters); }; performTest({ .check_valid = true, .to_mont = true }); diff --git a/include/bls12-381/fp.hpp b/include/bls12-381/fp.hpp index 32fd84f..5b042e9 100644 --- a/include/bls12-381/fp.hpp +++ b/include/bls12-381/fp.hpp @@ -225,7 +225,7 @@ class fp12 fp6 c1; fp12(); - explicit fp12(const std::array& eG2); + explicit fp12(const std::array& e2); fp12(const fp12& e); static std::optional fromBytesBE(const std::span in, const conv_opt opt = { .check_valid = true, .to_mont = true }); From 32cd7024686d83a2db510dbbaf56273e09415497 Mon Sep 17 00:00:00 2001 From: greg7mdp Date: Mon, 1 Apr 2024 18:52:36 -0400 Subject: [PATCH 4/8] Cleanup code by checking for positive condition --- src/fp.cpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/fp.cpp b/src/fp.cpp index 317dc74..61e9a21 100644 --- a/src/fp.cpp +++ b/src/fp.cpp @@ -37,26 +37,26 @@ optional fp::fromBytesLE(const span in, const conv_opt op void fp::toBytesBE(const span out, const from_mont fm /* = from_mont::yes */) const { - if(fm == from_mont::no) scalar::toBytesBE<6>(d, out); - else scalar::toBytesBE<6>(fromMont().d, out); + if(fm == from_mont::yes) scalar::toBytesBE<6>(fromMont().d, out); + else scalar::toBytesBE<6>(d, out); } void fp::toBytesLE(const span out, const from_mont fm /* = from_mont::yes */) const { - if(fm == from_mont::no) scalar::toBytesLE<6>(d, out); - else scalar::toBytesLE<6>(fromMont().d, out); + if(fm == from_mont::yes) scalar::toBytesLE<6>(fromMont().d, out); + else scalar::toBytesLE<6>(d, out); } array fp::toBytesBE(const from_mont fm /* = from_mont::yes */) const { - if(fm == from_mont::no) return scalar::toBytesBE<6>(d); - else return scalar::toBytesBE<6>(fromMont().d); + if(fm == from_mont::yes) return scalar::toBytesBE<6>(fromMont().d); + else return scalar::toBytesBE<6>(d); } array fp::toBytesLE(const from_mont fm /* = from_mont::yes */) const { - if(fm == from_mont::no) return scalar::toBytesLE<6>(d); - else return scalar::toBytesLE<6>(fromMont().d); + if(fm == from_mont::yes) return scalar::toBytesLE<6>(fromMont().d); + else return scalar::toBytesLE<6>(d); } fp fp::zero() From 3f176950d7b92c159b7c13ca68f8618c09698b02 Mon Sep 17 00:00:00 2001 From: greg7mdp Date: Mon, 1 Apr 2024 18:58:45 -0400 Subject: [PATCH 5/8] Fix `curve_check` flag wrongly changed. --- src/g.cpp | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/g.cpp b/src/g.cpp index c4c75d3..4a510d8 100644 --- a/src/g.cpp +++ b/src/g.cpp @@ -20,13 +20,14 @@ g1::g1(const g1& e) : x(e.x), y(e.y), z(e.z) optional g1::fromJacobianBytesBE(const span in, conv_opt opt) { // We decided to always validate the input here. Check flag will only affect on-curve checks. + bool curve_check = opt.check_valid; opt.check_valid = true; optional x = fp::fromBytesBE(span(&in[ 0], &in[ 48]), opt); optional y = fp::fromBytesBE(span(&in[48], &in[ 96]), opt); optional z = fp::fromBytesBE(span(&in[96], &in[144]), opt); if(!x || !y || !z) return {}; g1 p = g1({*x, *y, *z}); - if(opt.check_valid && !p.isOnCurve()) + if(curve_check && !p.isOnCurve()) { return {}; } @@ -36,13 +37,14 @@ optional g1::fromJacobianBytesBE(const span in, conv_opt optional g1::fromJacobianBytesLE(const span in, conv_opt opt) { // We decided to always validate the input here. Check flag will only affect on-curve checks. + bool curve_check = opt.check_valid; opt.check_valid = true; optional x = fp::fromBytesLE(span(&in[ 0], &in[ 48]), opt); optional y = fp::fromBytesLE(span(&in[48], &in[ 96]), opt); optional z = fp::fromBytesLE(span(&in[96], &in[144]), opt); if(!x || !y || !z) return {}; g1 p = g1({*x, *y, *z}); - if(opt.check_valid && !p.isOnCurve()) + if(curve_check && !p.isOnCurve()) { return {}; } @@ -52,6 +54,7 @@ optional g1::fromJacobianBytesLE(const span in, conv_opt optional g1::fromAffineBytesBE(const span in, conv_opt opt) { // We decided to always validate the input here. Check flag will only affect on-curve checks. + bool curve_check = opt.check_valid; opt.check_valid = true; optional x = fp::fromBytesBE(span(&in[ 0], &in[ 48]), opt); optional y = fp::fromBytesBE(span(&in[48], &in[ 96]), opt); @@ -63,7 +66,7 @@ optional g1::fromAffineBytesBE(const span in, conv_opt op } fp z = fp::one(); g1 p = g1({*x, *y, z}); - if(opt.check_valid && !p.isOnCurve()) + if(curve_check && !p.isOnCurve()) { return {}; } @@ -73,6 +76,7 @@ optional g1::fromAffineBytesBE(const span in, conv_opt op optional g1::fromAffineBytesLE(const span in, conv_opt opt) { // We decided to always validate the input here. Check flag will only affect on-curve checks. + bool curve_check = opt.check_valid; opt.check_valid = true; optional x = fp::fromBytesLE(span(&in[ 0], &in[ 48]), opt); optional y = fp::fromBytesLE(span(&in[48], &in[ 96]), opt); @@ -84,7 +88,7 @@ optional g1::fromAffineBytesLE(const span in, conv_opt op } fp z = fp::one(); g1 p = g1({*x, *y, z}); - if(opt.check_valid && !p.isOnCurve()) + if(curve_check && !p.isOnCurve()) { return {}; } From dde9128a3c28129e9349acf7dd23bfcf0dd3f814 Mon Sep 17 00:00:00 2001 From: greg7mdp Date: Mon, 1 Apr 2024 19:01:23 -0400 Subject: [PATCH 6/8] Fix `curve_check` flag wrongly changed - part 2. --- src/g.cpp | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/g.cpp b/src/g.cpp index 4a510d8..d77e560 100644 --- a/src/g.cpp +++ b/src/g.cpp @@ -733,13 +733,14 @@ g2::g2(const g2& e) : x(e.x), y(e.y), z(e.z) optional g2::fromJacobianBytesBE(const span in, conv_opt opt) { // We decided to always validate the input here. Check flag will only affect on-curve checks. + bool curve_check = opt.check_valid; opt.check_valid = true; optional x = fp2::fromBytesBE(span(&in[ 0], &in[ 96]), opt); optional y = fp2::fromBytesBE(span(&in[ 96], &in[192]), opt); optional z = fp2::fromBytesBE(span(&in[192], &in[288]), opt); if(!x || !y || !z) return {}; g2 p = g2({*x, *y, *z}); - if(opt.check_valid && !p.isOnCurve()) + if(curve_check && !p.isOnCurve()) { return {}; } @@ -749,13 +750,14 @@ optional g2::fromJacobianBytesBE(const span in, conv_opt optional g2::fromJacobianBytesLE(const span in, conv_opt opt) { // We decided to always validate the input here. Check flag will only affect on-curve checks. + bool curve_check = opt.check_valid; opt.check_valid = true; optional x = fp2::fromBytesLE(span(&in[ 0], &in[ 96]), opt); optional y = fp2::fromBytesLE(span(&in[ 96], &in[192]), opt); optional z = fp2::fromBytesLE(span(&in[192], &in[288]), opt); if(!x || !y || !z) return {}; g2 p = g2({*x, *y, *z}); - if(opt.check_valid && !p.isOnCurve()) + if(curve_check && !p.isOnCurve()) { return {}; } @@ -765,6 +767,7 @@ optional g2::fromJacobianBytesLE(const span in, conv_opt optional g2::fromAffineBytesBE(const span in, conv_opt opt) { // We decided to always validate the input here. Check flag will only affect on-curve checks. + bool curve_check = opt.check_valid; opt.check_valid = true; optional x = fp2::fromBytesBE(span(&in[ 0], &in[ 96]), opt); optional y = fp2::fromBytesBE(span(&in[ 96], &in[192]), opt); @@ -776,7 +779,7 @@ optional g2::fromAffineBytesBE(const span in, conv_opt o } fp2 z = fp2::one(); g2 p = g2({*x, *y, z}); - if(opt.check_valid && !p.isOnCurve()) + if(curve_check && !p.isOnCurve()) { return {}; } @@ -786,6 +789,7 @@ optional g2::fromAffineBytesBE(const span in, conv_opt o optional g2::fromAffineBytesLE(const span in, conv_opt opt) { // We decided to always validate the input here. Check flag will only affect on-curve checks. + bool curve_check = opt.check_valid; opt.check_valid = true; optional x = fp2::fromBytesLE(span(&in[ 0], &in[ 96]), opt); optional y = fp2::fromBytesLE(span(&in[ 96], &in[192]), opt); @@ -797,7 +801,7 @@ optional g2::fromAffineBytesLE(const span in, conv_opt o } fp2 z = fp2::one(); g2 p = g2({*x, *y, z}); - if(opt.check_valid && !p.isOnCurve()) + if(curve_check && !p.isOnCurve()) { return {}; } From 27f2fbdaa8c1fb9091c21c9b48b033eae5dc6ebf Mon Sep 17 00:00:00 2001 From: greg7mdp Date: Mon, 1 Apr 2024 19:06:23 -0400 Subject: [PATCH 7/8] Add a couple comments. --- include/bls12-381/fp.hpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/include/bls12-381/fp.hpp b/include/bls12-381/fp.hpp index 5b042e9..7feb0d0 100644 --- a/include/bls12-381/fp.hpp +++ b/include/bls12-381/fp.hpp @@ -11,14 +11,19 @@ namespace bls12_381 { +// config when converting from bytes +// --------------------------------- struct conv_opt { bool check_valid; // check bytes hold a valid encoding bool to_mont; // convert to montgomery form }; +// config when converting to bytes +// ------------------------------- enum class from_mont : uint8_t { no = 0, yes }; // element representation of 'fp' field which is the base field +// ------------------------------------------------------------ class fp { From 7f992aa13af0f804a0f9997c601e28067924eb65 Mon Sep 17 00:00:00 2001 From: greg7mdp Date: Tue, 2 Apr 2024 17:02:55 -0400 Subject: [PATCH 8/8] Fix `#include` statement. --- include/bls12-381/g.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/bls12-381/g.hpp b/include/bls12-381/g.hpp index fdaa920..ab53a7a 100644 --- a/include/bls12-381/g.hpp +++ b/include/bls12-381/g.hpp @@ -4,7 +4,7 @@ #include #include #include -#include "fp.hpp" +#include namespace bls12_381 {