diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 327a9839..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: git 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: | 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 } 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. */ 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'((?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'((? 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/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, 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 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;