From 15c23b19f05788352da56a2e3ef12eed729edfac Mon Sep 17 00:00:00 2001 From: Andy Polyakov Date: Thu, 13 Jun 2024 10:28:55 +0200 Subject: [PATCH 01/11] e{1,2}.c, vect.{c,h}: add EIP-2537 serialization. --- src/e1.c | 43 +++++++++++++++++++++++++++++++++++++++++++ src/e2.c | 53 +++++++++++++++++++++++++++++++++++++++++++++++++++++ src/vect.c | 29 +++++++++++++++++++++++++++++ src/vect.h | 2 ++ 4 files changed, 127 insertions(+) diff --git a/src/e1.c b/src/e1.c index f8a7be7b..a532796d 100644 --- a/src/e1.c +++ b/src/e1.c @@ -350,6 +350,49 @@ BLST_ERROR blst_p1_deserialize(POINTonE1_affine *out, const unsigned char in[96]) { return POINTonE1_Deserialize_Z(out, in); } +void blst_p1_affine_serialize_eip2537(unsigned char out[128], + const POINTonE1_affine *in) +{ + eip2537_from_fp(out, in->X); + eip2537_from_fp(out + 64, in->Y); +} + +void blst_p1_serialize_eip2537(unsigned char out[128], const POINTonE1 *in) +{ + if (vec_is_zero(in->Z, sizeof(in->Z))) { + bytes_zero(out, 128); + } else { + POINTonE1 p; + + if (!vec_is_equal(in->Z, BLS12_381_Rx.p, sizeof(in->Z))) { + POINTonE1_from_Jacobian(&p, in); + in = &p; + } + + eip2537_from_fp(out, in->X); + eip2537_from_fp(out + 64, in->Y); + } +} + +BLST_ERROR blst_p1_deserialize_eip2537(POINTonE1_affine *out, + const unsigned char in[128]) +{ + POINTonE1_affine ret; + + if (!fp_from_eip2537(ret.X, in)) + return BLST_BAD_ENCODING; + + if (!fp_from_eip2537(ret.Y, in + 64)) + return BLST_BAD_ENCODING; + + if (!POINTonE1_affine_on_curve(&ret)) + return BLST_POINT_NOT_ON_CURVE; + + vec_copy(out, &ret, sizeof(ret)); + + return BLST_SUCCESS; +} + #include "ec_ops.h" POINT_DADD_IMPL(POINTonE1, 384, fp) POINT_DADD_AFFINE_IMPL_A0(POINTonE1, 384, fp, BLS12_381_Rx.p) diff --git a/src/e2.c b/src/e2.c index 77f8064b..8b302717 100644 --- a/src/e2.c +++ b/src/e2.c @@ -409,6 +409,59 @@ BLST_ERROR blst_p2_deserialize(POINTonE2_affine *out, const unsigned char in[192]) { return POINTonE2_Deserialize_Z(out, in); } +void blst_p2_affine_serialize_eip2537(unsigned char out[256], + const POINTonE2_affine *in) +{ + eip2537_from_fp(out, in->X[0]); + eip2537_from_fp(out + 64, in->X[1]); + eip2537_from_fp(out + 128, in->Y[0]); + eip2537_from_fp(out + 192, in->Y[1]); +} + +void blst_p2_serialize_eip2537(unsigned char out[256], const POINTonE2 *in) +{ + if (vec_is_zero(in->Z, sizeof(in->Z))) { + bytes_zero(out, 256); + } else { + POINTonE2 p; + + if (!vec_is_equal(in->Z, BLS12_381_Rx.p, sizeof(in->Z))) { + POINTonE2_from_Jacobian(&p, in); + in = &p; + } + + eip2537_from_fp(out, in->X[0]); + eip2537_from_fp(out + 64, in->X[1]); + eip2537_from_fp(out + 128, in->Y[0]); + eip2537_from_fp(out + 192, in->Y[1]); + } +} + +BLST_ERROR blst_p2_deserialize_eip2537(POINTonE2_affine *out, + const unsigned char in[256]) +{ + POINTonE2_affine ret; + + if (!fp_from_eip2537(ret.X[0], in)) + return BLST_BAD_ENCODING; + + if (!fp_from_eip2537(ret.X[1], in + 64)) + return BLST_BAD_ENCODING; + + if (!fp_from_eip2537(ret.Y[0], in + 128)) + return BLST_BAD_ENCODING; + + if (!fp_from_eip2537(ret.Y[1], in + 192)) + return BLST_BAD_ENCODING; + + if (!POINTonE2_affine_on_curve(&ret)) + return BLST_POINT_NOT_ON_CURVE; + + vec_copy(out, &ret, sizeof(ret)); + + return BLST_SUCCESS; +} + #include "ec_ops.h" POINT_DADD_IMPL(POINTonE2, 384x, fp2) POINT_DADD_AFFINE_IMPL_A0(POINTonE2, 384x, fp2, BLS12_381_Rx.p2) diff --git a/src/vect.c b/src/vect.c index 1834a48f..bd56f6ec 100644 --- a/src/vect.c +++ b/src/vect.c @@ -174,3 +174,32 @@ static void div_by_z(limb_t val[]) } /* remainder is in low half of val[], quotient is in high */ } + +static void eip2537_from_fp(unsigned char out[64], const vec384 in) +{ + vec384 temp; + + from_fp(temp, in); + + bytes_zero(out, 16); + be_bytes_from_limbs(out + 16, temp, sizeof(vec384)); +} + +static bool_t fp_from_eip2537(vec384 ret, const unsigned char in[64]) +{ + vec512 out; + vec384 temp; + + limbs_from_be_bytes(out, in, sizeof(vec512)); + + if (!vec_is_zero(out + 48/sizeof(out[0]), 16)) + return 0; + + add_fp(temp, out, ZERO_384); /* less than modulus? */ + if (!vec_is_equal(temp, out, sizeof(temp))) + return 0; + + mul_fp(ret, temp, BLS12_381_RR); + + return 1; +} diff --git a/src/vect.h b/src/vect.h index 19640b11..f1a1e394 100644 --- a/src/vect.h +++ b/src/vect.h @@ -179,6 +179,8 @@ static void exp_mont_384x(vec384x out, const vec384x inp, const byte *pow, size_t pow_bits, const vec384 p, limb_t n0); static void div_by_zz(limb_t val[]); static void div_by_z(limb_t val[]); +static void eip2537_from_fp(unsigned char out[64], const vec384 in); +static bool_t fp_from_eip2537(vec384 ret, const unsigned char in[64]); #ifdef __UINTPTR_TYPE__ typedef __UINTPTR_TYPE__ uptr_t; From 20bbcc4de56d6deb5ac4efa598252e436a0db415 Mon Sep 17 00:00:00 2001 From: Andy Polyakov Date: Thu, 13 Jun 2024 10:33:17 +0200 Subject: [PATCH 02/11] bindings/blst_aux.h: add EIP-2537 serialization declarations. --- bindings/blst_aux.h | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/bindings/blst_aux.h b/bindings/blst_aux.h index 3de0850e..08ed485f 100644 --- a/bindings/blst_aux.h +++ b/bindings/blst_aux.h @@ -110,6 +110,14 @@ size_t blst_p2_sizeof(void); size_t blst_p2_affine_sizeof(void); size_t blst_fp12_sizeof(void); +void blst_p1_affine_serialize_eip2537(byte out[128], const blst_p1_affine *in); +void blst_p1_serialize_eip2537(byte out[128], const blst_p1 *in); +BLST_ERROR blst_p1_deserialize_eip2537(blst_p1_affine *out, const byte in[128]); + +void blst_p2_affine_serialize_eip2537(byte out[256], const blst_p2_affine *in); +void blst_p2_serialize_eip2537(byte out[256], const blst_p2 *in); +BLST_ERROR blst_p2_deserialize_eip2537(blst_p2_affine *out, const byte in[256]); + /* * Single-shot SHA-256 hash function. */ From 2c6bbec1570162a2804ae79add0d16bc9a7d1fba Mon Sep 17 00:00:00 2001 From: Andy Polyakov Date: Thu, 13 Jun 2024 10:34:42 +0200 Subject: [PATCH 03/11] bindings/blst.{hpp,swg}: add SWIG bindings for EIP-2537 serialization. --- bindings/blst.hpp | 36 ++++++++++++++++++------------------ bindings/blst.swg | 4 ++++ 2 files changed, 22 insertions(+), 18 deletions(-) diff --git a/bindings/blst.hpp b/bindings/blst.hpp index 127755be..8534ff7e 100644 --- a/bindings/blst.hpp +++ b/bindings/blst.hpp @@ -204,9 +204,10 @@ class P1_Affine { } #endif P1_Affine(const byte *in, size_t len) - { if (len == 0 || len != (in[0]&0x80 ? 48 : 96)) + { if (len == 0 || (len != (in[0]&0x80 ? 48 : 96) && len != 128)) throw BLST_BAD_ENCODING; - BLST_ERROR err = blst_p1_deserialize(&point, in); + BLST_ERROR err = len == 128 ? blst_p1_deserialize_eip2537(&point, in) + : blst_p1_deserialize(&point, in); if (err != BLST_SUCCESS) throw err; } @@ -214,6 +215,8 @@ class P1_Affine { P1_Affine dup() const { return *this; } P1 to_jacobian() const; + void serialize_eip2537(byte out[128]) const + { blst_p1_affine_serialize_eip2537(out, &point); } void serialize(byte out[96]) const { blst_p1_affine_serialize(out, &point); } void compress(byte out[48]) const @@ -264,18 +267,15 @@ class P1 { } #endif P1(const byte *in, size_t len) - { if (len == 0 || len != (in[0]&0x80 ? 48 : 96)) - throw BLST_BAD_ENCODING; - blst_p1_affine a; - BLST_ERROR err = blst_p1_deserialize(&a, in); - if (err != BLST_SUCCESS) - throw err; - blst_p1_from_affine(&point, &a); + { P1_Affine affine{in, len}; + blst_p1_from_affine(&point, &affine.point); } P1(const P1_Affine& affine) { blst_p1_from_affine(&point, affine); } P1 dup() const { return *this; } P1_Affine to_affine() const { return P1_Affine(*this); } + void serialize_eip2537(byte out[128]) const + { blst_p1_serialize_eip2537(out, &point); } void serialize(byte out[96]) const { blst_p1_serialize(out, &point); } void compress(byte out[48]) const { blst_p1_compress(out, &point); } bool on_curve() const { return blst_p1_on_curve(&point); } @@ -502,9 +502,10 @@ class P2_Affine { } #endif P2_Affine(const byte *in, size_t len) - { if (len == 0 || len != (in[0]&0x80 ? 96 : 192)) + { if (len == 0 || (len != (in[0]&0x80 ? 96 : 192) && len != 256)) throw BLST_BAD_ENCODING; - BLST_ERROR err = blst_p2_deserialize(&point, in); + BLST_ERROR err = len == 256 ? blst_p2_deserialize_eip2537(&point, in) + : blst_p2_deserialize(&point, in); if (err != BLST_SUCCESS) throw err; } @@ -512,6 +513,8 @@ class P2_Affine { P2_Affine dup() const { return *this; } P2 to_jacobian() const; + void serialize_eip2537(byte out[256]) const + { blst_p2_affine_serialize_eip2537(out, &point); } void serialize(byte out[192]) const { blst_p2_affine_serialize(out, &point); } void compress(byte out[96]) const @@ -562,18 +565,15 @@ class P2 { } #endif P2(const byte *in, size_t len) - { if (len == 0 || len != (in[0]&0x80 ? 96 : 192)) - throw BLST_BAD_ENCODING; - blst_p2_affine a; - BLST_ERROR err = blst_p2_deserialize(&a, in); - if (err != BLST_SUCCESS) - throw err; - blst_p2_from_affine(&point, &a); + { P2_Affine affine{in, len}; + blst_p2_from_affine(&point, &affine.point); } P2(const P2_Affine& affine) { blst_p2_from_affine(&point, affine); } P2 dup() const { return *this; } P2_Affine to_affine() const { return P2_Affine(*this); } + void serialize_eip2537(byte out[256]) const + { blst_p2_serialize(out, &point); } void serialize(byte out[192]) const { blst_p2_serialize(out, &point); } void compress(byte out[96]) const { blst_p2_compress(out, &point); } bool on_curve() const { return blst_p2_on_curve(&point); } diff --git a/bindings/blst.swg b/bindings/blst.swg index 4cb9c30d..34eb27c4 100644 --- a/bindings/blst.swg +++ b/bindings/blst.swg @@ -689,6 +689,10 @@ import java.nio.file.*; void blst_p2_serialize, void blst_p2_affine_serialize, void compress, void blst_p1_compress, void blst_p1_affine_compress, void blst_p2_compress, void blst_p2_affine_compress, + void serialize_eip2537, void blst_p1_serialize_eip2537, + void blst_p2_serialize_eip2537, + void blst_p1_affine_serialize_eip2537, + void blst_p2_affine_serialize_eip2537, void blst_sk_to_pk2_in_g1, void blst_sign_pk2_in_g1, void blst_sk_to_pk2_in_g2, void blst_sign_pk2_in_g2 } From 11f9015110ea286b3820f8b491885234ab7eb7f6 Mon Sep 17 00:00:00 2001 From: Andy Polyakov Date: Thu, 13 Jun 2024 11:19:38 +0200 Subject: [PATCH 04/11] .github/workflows/ci.yml: fix Emscripten test. --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 327a9839..d1149dc5 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -264,7 +264,7 @@ jobs: registry: https://index.docker.io/v1/ image: emscripten/emsdk options: --volume ${{ github.workspace }}:/blst --network=none - run: git clone -q /blst /tmp/blst && /tmp/blst/bindings/emscripten/run.me -O2 + run: git -c safe.directory="*" clone -q /blst /tmp/blst && /tmp/blst/bindings/emscripten/run.me -O2 - name: C# run: | From f9f0509c4ca2badc29a74c982269b07127c7504a Mon Sep 17 00:00:00 2001 From: Andy Polyakov Date: Thu, 13 Jun 2024 11:24:33 +0200 Subject: [PATCH 05/11] fixup! .github/workflows/ci.yml: fix Emscripten test. --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index d1149dc5..fbf7dc3d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -264,7 +264,7 @@ jobs: registry: https://index.docker.io/v1/ image: emscripten/emsdk options: --volume ${{ github.workspace }}:/blst --network=none - run: git -c safe.directory="*" clone -q /blst /tmp/blst && /tmp/blst/bindings/emscripten/run.me -O2 + run: set -x && git -c safe.directory="*" clone -q /blst /tmp/blst && /tmp/blst/bindings/emscripten/run.me -O2 - name: C# run: | From 2df86270e1cad05f18cd597ff2c9a0337563cff4 Mon Sep 17 00:00:00 2001 From: Andy Polyakov Date: Thu, 13 Jun 2024 12:09:15 +0200 Subject: [PATCH 06/11] fixup! .github/workflows/ci.yml: fix Emscripten test. --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index fbf7dc3d..a96186da 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -264,7 +264,7 @@ jobs: registry: https://index.docker.io/v1/ image: emscripten/emsdk options: --volume ${{ github.workspace }}:/blst --network=none - run: set -x && git -c safe.directory="*" clone -q /blst /tmp/blst && /tmp/blst/bindings/emscripten/run.me -O2 + run: set -x && git config --global safe.directory \* && git clone -q /blst /tmp/blst && /tmp/blst/bindings/emscripten/run.me -O2 - name: C# run: | From 14da1a1da6104bf30f6ed54a6cfdc019b3ace18b Mon Sep 17 00:00:00 2001 From: Andy Polyakov Date: Thu, 13 Jun 2024 13:06:35 +0200 Subject: [PATCH 07/11] bindings/c#: add EIP-2537 serialization. --- bindings/c#/run.me | 38 +++++++++++++--- bindings/c#/supranational.blst.cs | 72 +++++++++++++++++++++++++------ 2 files changed, 91 insertions(+), 19 deletions(-) diff --git a/bindings/c#/run.me b/bindings/c#/run.me index a7a1f42b..124710c2 100755 --- a/bindings/c#/run.me +++ b/bindings/c#/run.me @@ -348,6 +348,13 @@ static extern ERROR blst_core_verify_pk_in_g2([In] long[] pk, [In] long[] sig, [In] byte[] dst, size_t dst_len, [In] byte[] aug, size_t aug_len); +[DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)] +static extern ERROR blst_p1_deserialize_eip2537([Out] long[] ret, + [In] byte[] inp); +[DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)] +static extern void blst_p1_affine_serialize_eip2537([Out] byte[] ret, + [In] long[] inp); + public struct P1_Affine { internal readonly long[] point; @@ -359,10 +366,12 @@ public struct P1_Affine { public P1_Affine(byte[] inp) : this(true) { int len = inp.Length; - if (len == 0 || len != ((inp[0]&0x80) == 0x80 ? P1_COMPRESSED_SZ - : 2*P1_COMPRESSED_SZ)) + if (len == 0 || (len != ((inp[0]&0x80) == 0x80 ? P1_COMPRESSED_SZ + : 2*P1_COMPRESSED_SZ) && + len != 128*1)) throw new Exception(ERROR.BAD_ENCODING); - ERROR err = blst_p1_deserialize(point, inp); + ERROR err = len == 128*1 ? blst_p1_deserialize_eip2537(point, inp) + : blst_p1_deserialize(point, inp); if (err != ERROR.SUCCESS) throw new Exception(err); } @@ -371,6 +380,11 @@ public struct P1_Affine { public P1_Affine dup() { return new P1_Affine(this); } public P1 to_jacobian() { return new P1(this); } + public byte[] serialize_eip2537() + { byte[] ret = new byte[128*1]; + blst_p1_affine_serialize_eip2537(ret, point); + return ret; + } public byte[] serialize() { byte[] ret = new byte[2*P1_COMPRESSED_SZ]; blst_p1_affine_serialize(ret, point); @@ -455,6 +469,9 @@ void blst_p1_add_or_double_affine([Out] long[] ret, [In] long[] a, [DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)] static extern void blst_p1_double([Out] long[] ret, [In] long[] a); +[DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)] +static extern void blst_p1_serialize_eip2537([Out] byte[] ret, [In] long[] inp); + public struct P1 { internal long[] point; @@ -470,10 +487,12 @@ public struct P1 { { blst_sk_to_pk_in_g1(point, sk.key); } public P1(byte[] inp) : this(true) { int len = inp.Length; - if (len == 0 || len != ((inp[0]&0x80) == 0x80 ? P1_COMPRESSED_SZ - : 2*P1_COMPRESSED_SZ)) + if (len == 0 || (len != ((inp[0]&0x80) == 0x80 ? P1_COMPRESSED_SZ + : 2*P1_COMPRESSED_SZ) && + len != 128*1)) throw new Exception(ERROR.BAD_ENCODING); - ERROR err = blst_p1_deserialize(point, inp); + ERROR err = len == 128*1 ? blst_p1_deserialize_eip2537(point, inp) + : blst_p1_deserialize(point, inp); if (err != ERROR.SUCCESS) throw new Exception(err); blst_p1_from_affine(point, point); @@ -483,6 +502,11 @@ public struct P1 { public P1 dup() { return new P1(this); } public P1_Affine to_affine() { return new P1_Affine(this); } + public byte[] serialize_eip2537() + { byte[] ret = new byte[128*1]; + blst_p1_serialize_eip2537(ret, point); + return ret; + } public byte[] serialize() { byte[] ret = new byte[2*P1_COMPRESSED_SZ]; blst_p1_serialize(ret, point); @@ -789,7 +813,7 @@ if newer([here[-1], fname]): print("\n\n", file=fd) print(top, file=fd) print(middle, file=fd) - print(re.sub(r'((? Date: Thu, 13 Jun 2024 15:17:55 +0200 Subject: [PATCH 08/11] bindings/emscripten: add EIP-2537 serialization. --- bindings/emscripten/build.py | 32 ++++++++++++++++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) diff --git a/bindings/emscripten/build.py b/bindings/emscripten/build.py index eb76504f..1bb7dea2 100755 --- a/bindings/emscripten/build.py +++ b/bindings/emscripten/build.py @@ -184,6 +184,20 @@ { return wrapPointer(_P1_Affine_to_jacobian_0(this.ptr), P1); };; """ p1_cpp += """ +byte* EMSCRIPTEN_KEEPALIVE P1_Affine_serialize_eip2537_0(const P1_Affine* self) +{ byte out[128*1]; + self->serialize_eip2537(out); + return out; +} +""" +p1_js += """ +P1_Affine.prototype['serialize_eip2537'] = P1_Affine.prototype.serialize_eip2537 = /** @this{Object} */ +function() +{ var out = _P1_Affine_serialize_eip2537_0(this.ptr); + return new Uint8Array(HEAPU8.subarray(out, out + 128*1)); +};; +""" +p1_cpp += """ byte* EMSCRIPTEN_KEEPALIVE P1_Affine_serialize_0(const P1_Affine* self) { byte out[96*1]; self->serialize(out); @@ -340,6 +354,20 @@ { return wrapPointer(_P1_to_affine_0(this.ptr), P1_Affine); };; """ p1_cpp += """ +byte* EMSCRIPTEN_KEEPALIVE P1_serialize_eip2537_0(const P1* self) +{ byte out[128*1]; + self->serialize_eip2537(out); + return out; +} +""" +p1_js += """ +P1.prototype['serialize_eip2537'] = P1.prototype.serialize_eip2537 = /** @this{Object} */ +function() +{ var out = _P1_serialize_eip2537_0(this.ptr); + return new Uint8Array(HEAPU8.subarray(out, out + 96*1)); +};; +""" +p1_cpp += """ byte* EMSCRIPTEN_KEEPALIVE P1_serialize_0(const P1* self) { byte out[96*1]; self->serialize(out); @@ -1151,7 +1179,7 @@ def xchg_1vs2(matchobj): print("//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!", file=fd) print(common_cpp, file=fd) print(p1_cpp, file=fd) -print(re.sub(r'((? Date: Thu, 13 Jun 2024 15:24:19 +0200 Subject: [PATCH 09/11] Execute build/refresh.sh. --- bindings/rust/src/bindings.rs | 20 +++++++++++++++++++- build/win64/blst.def | 6 ++++++ 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/bindings/rust/src/bindings.rs b/bindings/rust/src/bindings.rs index f72753c3..371772f7 100644 --- a/bindings/rust/src/bindings.rs +++ b/bindings/rust/src/bindings.rs @@ -1,4 +1,4 @@ -/* automatically generated by rust-bindgen 0.65.1 */ +/* automatically generated by rust-bindgen 0.69.4 */ #[repr(u32)] #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] @@ -1386,6 +1386,24 @@ extern "C" { extern "C" { pub fn blst_fp12_sizeof() -> usize; } +extern "C" { + pub fn blst_p1_affine_serialize_eip2537(out: *mut byte, in_: *const blst_p1_affine); +} +extern "C" { + pub fn blst_p1_serialize_eip2537(out: *mut byte, in_: *const blst_p1); +} +extern "C" { + pub fn blst_p1_deserialize_eip2537(out: *mut blst_p1_affine, in_: *const byte) -> BLST_ERROR; +} +extern "C" { + pub fn blst_p2_affine_serialize_eip2537(out: *mut byte, in_: *const blst_p2_affine); +} +extern "C" { + pub fn blst_p2_serialize_eip2537(out: *mut byte, in_: *const blst_p2); +} +extern "C" { + pub fn blst_p2_deserialize_eip2537(out: *mut blst_p2_affine, in_: *const byte) -> BLST_ERROR; +} extern "C" { pub fn blst_sha256(out: *mut byte, msg: *const byte, msg_len: usize); } diff --git a/build/win64/blst.def b/build/win64/blst.def index dda95336..30625fc3 100644 --- a/build/win64/blst.def +++ b/build/win64/blst.def @@ -217,5 +217,11 @@ EXPORTS blst_p2_sizeof blst_p2_affine_sizeof blst_fp12_sizeof + blst_p1_affine_serialize_eip2537 + blst_p1_serialize_eip2537 + blst_p1_deserialize_eip2537 + blst_p2_affine_serialize_eip2537 + blst_p2_serialize_eip2537 + blst_p2_deserialize_eip2537 blst_sha256 From 06c6820522c46acac0bc7b93ceb137ea8588e622 Mon Sep 17 00:00:00 2001 From: Andy Polyakov Date: Tue, 18 Jun 2024 21:03:34 +0200 Subject: [PATCH 10/11] bindings/rust: add EIP-2537 serialization. --- bindings/rust/src/lib.rs | 59 +++++++++++++++++++++++++++++++++++----- 1 file changed, 52 insertions(+), 7 deletions(-) diff --git a/bindings/rust/src/lib.rs b/bindings/rust/src/lib.rs index 49dac393..7e4e1c8e 100644 --- a/bindings/rust/src/lib.rs +++ b/bindings/rust/src/lib.rs @@ -526,19 +526,25 @@ macro_rules! sig_variant_impl { $pk_from_aff:ident, $pk_ser:ident, $pk_comp:ident, + $pk_ser_eip2537:ident, $pk_deser:ident, $pk_uncomp:ident, + $pk_deser_eip2537:ident, $pk_comp_size:expr, $pk_ser_size:expr, + $pk_eip2537_size:expr, $sig_in_group:ident, $sig_to_aff:ident, $sig_from_aff:ident, $sig_ser:ident, $sig_comp:ident, + $sig_ser_eip2537:ident, $sig_deser:ident, $sig_uncomp:ident, + $sig_deser_eip2537:ident, $sig_comp_size:expr, $sig_ser_size:expr, + $sig_eip2537_size:expr, $pk_add_or_dbl:ident, $pk_add_or_dbl_aff:ident, $sig_add_or_dbl:ident, @@ -829,6 +835,14 @@ macro_rules! sig_variant_impl { pk_out } + pub fn serialize_eip2537(&self) -> [u8; $pk_eip2537_size] { + let mut pk_out = [0u8; $pk_eip2537_size]; + unsafe { + $pk_ser_eip2537(pk_out.as_mut_ptr(), &self.point); + } + pk_out + } + pub fn uncompress(pk_comp: &[u8]) -> Result { if pk_comp.len() == $pk_comp_size && (pk_comp[0] & 0x80) != 0 { let mut pk = <$pk_aff>::default(); @@ -843,11 +857,17 @@ macro_rules! sig_variant_impl { } pub fn deserialize(pk_in: &[u8]) -> Result { - if (pk_in.len() == $pk_ser_size && (pk_in[0] & 0x80) == 0) - || (pk_in.len() == $pk_comp_size && (pk_in[0] & 0x80) != 0) + let len = pk_in.len(); + if (len == $pk_ser_size && (pk_in[0] & 0x80) == 0) + || (len == $pk_comp_size && (pk_in[0] & 0x80) != 0) + || (len == $pk_eip2537_size) { let mut pk = <$pk_aff>::default(); - let err = unsafe { $pk_deser(&mut pk, pk_in.as_ptr()) }; + let err = if len == $pk_eip2537_size { + unsafe { $pk_deser_eip2537(&mut pk, pk_in.as_ptr()) } + } else { + unsafe { $pk_deser(&mut pk, pk_in.as_ptr()) } + }; if err != BLST_ERROR::BLST_SUCCESS { return Err(err); } @@ -1312,6 +1332,14 @@ macro_rules! sig_variant_impl { sig_out } + pub fn serialize_eip2537(&self) -> [u8; $sig_eip2537_size] { + let mut sig_out = [0; $sig_eip2537_size]; + unsafe { + $sig_ser_eip2537(sig_out.as_mut_ptr(), &self.point); + } + sig_out + } + pub fn uncompress(sig_comp: &[u8]) -> Result { if sig_comp.len() == $sig_comp_size && (sig_comp[0] & 0x80) != 0 { @@ -1328,12 +1356,17 @@ macro_rules! sig_variant_impl { } pub fn deserialize(sig_in: &[u8]) -> Result { - if (sig_in.len() == $sig_ser_size && (sig_in[0] & 0x80) == 0) - || (sig_in.len() == $sig_comp_size - && (sig_in[0] & 0x80) != 0) + let len = sig_in.len(); + if (len == $sig_ser_size && (sig_in[0] & 0x80) == 0) + || (len == $sig_comp_size && (sig_in[0] & 0x80) != 0) + || (len == $sig_eip2537_size) { let mut sig = <$sig_aff>::default(); - let err = unsafe { $sig_deser(&mut sig, sig_in.as_ptr()) }; + let err = if len == $sig_eip2537_size { + unsafe { $sig_deser_eip2537(&mut sig, sig_in.as_ptr()) } + } else { + unsafe { $sig_deser(&mut sig, sig_in.as_ptr()) } + }; if err != BLST_ERROR::BLST_SUCCESS { return Err(err); } @@ -1904,19 +1937,25 @@ pub mod min_pk { blst_p1_from_affine, blst_p1_affine_serialize, blst_p1_affine_compress, + blst_p1_affine_serialize_eip2537, blst_p1_deserialize, blst_p1_uncompress, + blst_p1_deserialize_eip2537, 48, 96, + 128, blst_p2_affine_in_g2, blst_p2_to_affine, blst_p2_from_affine, blst_p2_affine_serialize, blst_p2_affine_compress, + blst_p2_affine_serialize_eip2537, blst_p2_deserialize, blst_p2_uncompress, + blst_p2_deserialize_eip2537, 96, 192, + 256, blst_p1_add_or_double, blst_p1_add_or_double_affine, blst_p2_add_or_double, @@ -1948,19 +1987,25 @@ pub mod min_sig { blst_p2_from_affine, blst_p2_affine_serialize, blst_p2_affine_compress, + blst_p2_affine_serialize_eip2537, blst_p2_deserialize, blst_p2_uncompress, + blst_p2_deserialize_eip2537, 96, 192, + 256, blst_p1_affine_in_g1, blst_p1_to_affine, blst_p1_from_affine, blst_p1_affine_serialize, blst_p1_affine_compress, + blst_p1_affine_serialize_eip2537, blst_p1_deserialize, blst_p1_uncompress, + blst_p1_deserialize_eip2537, 48, 96, + 128, blst_p2_add_or_double, blst_p2_add_or_double_affine, blst_p1_add_or_double, From 9b570f2ac5eef08b6e7069d5a21bbf4ae632b8d9 Mon Sep 17 00:00:00 2001 From: Andy Polyakov Date: Tue, 18 Jun 2024 21:04:40 +0200 Subject: [PATCH 11/11] bindings/go: add EIP-2537 serialization. --- bindings/go/blst.go | 50 ++++++++++++++++++++++++++++++++++------- bindings/go/blst.tgo | 2 ++ bindings/go/blst_px.tgo | 24 ++++++++++++++++---- bindings/go/generate.py | 2 +- 4 files changed, 65 insertions(+), 13 deletions(-) diff --git a/bindings/go/blst.go b/bindings/go/blst.go index b0713780..0ca9a337 100644 --- a/bindings/go/blst.go +++ b/bindings/go/blst.go @@ -165,8 +165,10 @@ const BLST_SCALAR_BYTES = 256 / 8 const BLST_FP_BYTES = 384 / 8 const BLST_P1_COMPRESS_BYTES = BLST_FP_BYTES const BLST_P1_SERIALIZE_BYTES = BLST_FP_BYTES * 2 +const BLST_P1_SERIALIZE_EIP2537_BYTES = 64 * 2 const BLST_P2_COMPRESS_BYTES = BLST_FP_BYTES * 2 const BLST_P2_SERIALIZE_BYTES = BLST_FP_BYTES * 4 +const BLST_P2_SERIALIZE_EIP2537_BYTES = 128 * 2 type Scalar = C.blst_scalar type Fp = C.blst_fp @@ -1705,11 +1707,22 @@ func (p1 *P1Affine) Serialize() []byte { return out[:] } +func (p1 *P1Affine) SerializeEip2537() []byte { + var out [BLST_P1_SERIALIZE_EIP2537_BYTES]byte + C.blst_p1_affine_serialize_eip2537((*C.byte)(&out[0]), p1) + return out[:] +} + func (p1 *P1Affine) Deserialize(in []byte) *P1Affine { - if len(in) != BLST_P1_SERIALIZE_BYTES { - return nil - } - if C.blst_p1_deserialize(p1, (*C.byte)(&in[0])) != C.BLST_SUCCESS { + if len(in) == BLST_P1_SERIALIZE_BYTES { + if C.blst_p1_deserialize(p1, (*C.byte)(&in[0])) != C.BLST_SUCCESS { + return nil + } + } else if len(in) == BLST_P1_SERIALIZE_EIP2537_BYTES { + if C.blst_p1_deserialize_eip2537(p1, (*C.byte)(&in[0])) != C.BLST_SUCCESS { + return nil + } + } else { return nil } return p1 @@ -1797,6 +1810,11 @@ func (p1 *P1) Serialize() []byte { C.blst_p1_serialize((*C.byte)(&out[0]), p1) return out[:] } +func (p1 *P1) SerializeEip2537() []byte { + var out [BLST_P1_SERIALIZE_EIP2537_BYTES]byte + C.blst_p1_serialize_eip2537((*C.byte)(&out[0]), p1) + return out[:] +} func (p1 *P1) Compress() []byte { var out [BLST_P1_COMPRESS_BYTES]byte C.blst_p1_compress((*C.byte)(&out[0]), p1) @@ -2367,11 +2385,22 @@ func (p2 *P2Affine) Serialize() []byte { return out[:] } +func (p2 *P2Affine) SerializeEip2537() []byte { + var out [BLST_P2_SERIALIZE_EIP2537_BYTES]byte + C.blst_p2_affine_serialize_eip2537((*C.byte)(&out[0]), p2) + return out[:] +} + func (p2 *P2Affine) Deserialize(in []byte) *P2Affine { - if len(in) != BLST_P2_SERIALIZE_BYTES { - return nil - } - if C.blst_p2_deserialize(p2, (*C.byte)(&in[0])) != C.BLST_SUCCESS { + if len(in) == BLST_P2_SERIALIZE_BYTES { + if C.blst_p2_deserialize(p2, (*C.byte)(&in[0])) != C.BLST_SUCCESS { + return nil + } + } else if len(in) == BLST_P2_SERIALIZE_EIP2537_BYTES { + if C.blst_p2_deserialize_eip2537(p2, (*C.byte)(&in[0])) != C.BLST_SUCCESS { + return nil + } + } else { return nil } return p2 @@ -2459,6 +2488,11 @@ func (p2 *P2) Serialize() []byte { C.blst_p2_serialize((*C.byte)(&out[0]), p2) return out[:] } +func (p2 *P2) SerializeEip2537() []byte { + var out [BLST_P2_SERIALIZE_EIP2537_BYTES]byte + C.blst_p2_serialize_eip2537((*C.byte)(&out[0]), p2) + return out[:] +} func (p2 *P2) Compress() []byte { var out [BLST_P2_COMPRESS_BYTES]byte C.blst_p2_compress((*C.byte)(&out[0]), p2) diff --git a/bindings/go/blst.tgo b/bindings/go/blst.tgo index 32887e06..a42592e7 100644 --- a/bindings/go/blst.tgo +++ b/bindings/go/blst.tgo @@ -155,8 +155,10 @@ const BLST_SCALAR_BYTES = 256 / 8 const BLST_FP_BYTES = 384 / 8 const BLST_P1_COMPRESS_BYTES = BLST_FP_BYTES const BLST_P1_SERIALIZE_BYTES = BLST_FP_BYTES * 2 +const BLST_P1_SERIALIZE_EIP2537_BYTES = 64 * 2 const BLST_P2_COMPRESS_BYTES = BLST_FP_BYTES * 2 const BLST_P2_SERIALIZE_BYTES = BLST_FP_BYTES * 4 +const BLST_P2_SERIALIZE_EIP2537_BYTES = 128 * 2 type Scalar = C.blst_scalar type Fp = C.blst_fp diff --git a/bindings/go/blst_px.tgo b/bindings/go/blst_px.tgo index 187d79d3..bb9d5d56 100644 --- a/bindings/go/blst_px.tgo +++ b/bindings/go/blst_px.tgo @@ -45,11 +45,22 @@ func (p1 *P1Affine) Serialize() []byte { return out[:] } +func (p1 *P1Affine) SerializeEip2537() []byte { + var out [BLST_P1_SERIALIZE_EIP2537_BYTES]byte + C.blst_p1_affine_serialize_eip2537((*C.byte)(&out[0]), p1) + return out[:] +} + func (p1 *P1Affine) Deserialize(in []byte) *P1Affine { - if len(in) != BLST_P1_SERIALIZE_BYTES { - return nil - } - if C.blst_p1_deserialize(p1, (*C.byte)(&in[0])) != C.BLST_SUCCESS { + if len(in) == BLST_P1_SERIALIZE_BYTES { + if C.blst_p1_deserialize(p1, (*C.byte)(&in[0])) != C.BLST_SUCCESS { + return nil + } + } else if len(in) == BLST_P1_SERIALIZE_EIP2537_BYTES { + if C.blst_p1_deserialize_eip2537(p1, (*C.byte)(&in[0])) != C.BLST_SUCCESS { + return nil + } + } else { return nil } return p1 @@ -137,6 +148,11 @@ func (p1 *P1) Serialize() []byte { C.blst_p1_serialize((*C.byte)(&out[0]), p1) return out[:] } +func (p1 *P1) SerializeEip2537() []byte { + var out [BLST_P1_SERIALIZE_EIP2537_BYTES]byte + C.blst_p1_serialize_eip2537((*C.byte)(&out[0]), p1) + return out[:] +} func (p1 *P1) Compress() []byte { var out [BLST_P1_COMPRESS_BYTES]byte C.blst_p1_compress((*C.byte)(&out[0]), p1) diff --git a/bindings/go/generate.py b/bindings/go/generate.py index d40fad21..57e43880 100755 --- a/bindings/go/generate.py +++ b/bindings/go/generate.py @@ -81,7 +81,7 @@ def remap(fout, fin, mapping, dont_touch, removeImports): # These are strings that overlap with the mapping names but we don't # actually want to change. The second value should be a unique string. -dont_touch = (('Fp12', 'foo1234'),) +dont_touch = (('Fp12', 'foo1234'), ('2537', 'bar1234')) # We're going to swap these names to get from min-pk to min-sig mapping = [('P1', 'P2'),