Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Nonsence output #9

Open
ivanstepanovftw opened this issue Jul 5, 2024 · 4 comments
Open

Nonsence output #9

ivanstepanovftw opened this issue Jul 5, 2024 · 4 comments

Comments

@ivanstepanovftw
Copy link

ivanstepanovftw commented Jul 5, 2024

Doing everything as in README.md:

using namespace gec::bigint::literal;

// Elliptic curves need to be defined before any ECC operations can be carried out. Take secp256k1 as an example, define the finite field Field for secp256k1 first.

// use uint64 x 4 to store a single element on finite field
using Bigint256 = gec::bigint::ArrayBE<uint64_t, 4>;

// define parameters required by montgomery multiplication:
// cardinality of finite field
GEC_DEF_GLOBAL(MOD, Bigint256, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f_int);
constexpr Bigint256::LimbT MOD_P = 0xd838091dd2253531ull; // -MOD^-1 mod 2^64
GEC_DEF_GLOBAL(RR, Bigint256, 0x01000007a2000e90a1_int); // 2^512 mod MOD
GEC_DEF_GLOBAL(ONE_R, Bigint256, 0x1000003d1_int); // 2^256 mod MOD

// define the finite field type
using Field = GEC_BASE_FIELD(Bigint256, MOD, MOD_P, RR, ONE_R);

// Then define Scalar as the scalar of secp256k1.

// define parameters required by montgomery multiplication:
// cardinality of the elliptic curve
GEC_DEF_GLOBAL(CARD, Bigint256, 0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141_int);
constexpr Bigint256::LimbT CARD_P = 0x4b0dff665588b13full; // -CARD^-1 mod 2^64
GEC_DEF_GLOBAL(CARD_RR, Bigint256, 0x9d671cd581c69bc5e697f5e45bcd07c6741496c20e7cf878896cf21467d7d140_int); // 2^512 mod CARD
GEC_DEF_GLOBAL(CARD_ONE_R, Bigint256, 0x14551231950b75fc4402da1732fc9bebf_int);// 2^256 mod CARD

// define the scalar type
using Scalar = GEC_BASE_FIELD(Bigint256, CARD, CARD_P, CARD_RR, CARD_ONE_R);

// Finally, define Secp256k1 as curve secp256k1.

// parameters of the elliptic curve, in montgomery form
GEC_DEF_GLOBAL(A, Field, 0); // = A * 2^256 mod MOD
GEC_DEF_GLOBAL(B, Field, 0x700001ab7_int); // = B * 2^256 mod MOD

// define the curve with Jacobian coordinate
using Secp256k1_ = GEC_CURVE(gec::curve::JacobianCurve, Field, A, B);
// use the specialized implementation for curves whose A = 0 to boost performance
using Secp256k1 = GEC_CURVE_B(gec::curve::JacobianCurve, Field, B);

// define the generator, in montgomery form
GEC_DEF_GLOBAL(GEN, Secp256k1, (
    Field(0x9981e643e9089f48979f48c033fd129c231e295329bc66dbd7362e5a487e2097_int),
    Field(0xcf3f851fd4a582d670b6b59aac19c1368dfc5d5d1f1dc64db15ea6d2d3dbabe2_int),
    Field(0x1000003d1_int)
));

__global__ void kernel_create_eth_public_keys(eth_private_key * private_keys, eth_public_key * public_keys, uint32_t count) {
    uint32_t idx = blockIdx.x * blockDim.x + threadIdx.x;
    if (idx >= count)
        return;

    // Load the private key
    Scalar priv_key;
    memcpy(priv_key.arr, private_keys[idx]._limbs, sizeof(eth_private_key));

    // Perform elliptic curve scalar multiplication
    Secp256k1 pub_key;
    Secp256k1::mul(pub_key, priv_key, d_GEN);

    // Store the public key
    memcpy(public_keys[idx].x._limbs, pub_key.x().arr, sizeof(eth_public_key) / 2);
    memcpy(public_keys[idx].y._limbs, pub_key.y().arr, sizeof(eth_public_key) / 2);
    
    // Debug
    printf("private_key: { ");
    for (int i = 0; i < sizeof(priv_key.arr) / sizeof(*priv_key.arr); ++i) {
        printf("%016lx, ", priv_key.arr[i]);
    }
    printf("}\n");

    printf("public_key: { x: { ");
    for (int i = 0; i < sizeof(pub_key.x().arr) / sizeof(*pub_key.x().arr); ++i) {
        printf("%016lx, ", pub_key.x().arr[i]);
    }
    printf("}, y: { ");
    for (int i = 0; i < sizeof(pub_key.y().arr) / sizeof(*pub_key.y().arr); ++i) {
        printf("%016lx, ", pub_key.y().arr[i]);
    }
    printf("}, z: { ");
    for (int i = 0; i < sizeof(pub_key.z().arr) / sizeof(*pub_key.z().arr); ++i) {
        printf("%016lx, ", pub_key.z().arr[i]);
    }
    printf("} }\n");
}

And I'm getting the following:

private_key: { 703e556dbd7f03b6, 283067fd845af0c5, 7666f33f1245241f, 5450d66d3a46d453, }
public_key: { x: { 0000000900002259, 0000000000000000, 0000000000000000, 0000000000000000, }, y: { ffffffe3ffff9524, ffffffffffffffff, ffffffffffffffff, ffffffffffffffff, }, z: { 0000000000000000, 0000000000000000, 0000000000000000, 0000000000000000, } }

For this private key, it should be

public_key: { x: { 3d67a201808ae629, dfe044a756acbf82, 9bda7c80a653d4d4, 3c07eb284e1e6696 }, y: { 83cdb5a6704dcb70, e3c05e25f5d45805, 666eda0d9e7d5b83, caf2306259be9167 } z: { 1021a492b0450fe2, 3d74d41de68a50d6, 8189b2b7571ef9d9, 1dd2ce02dccec4e1 } }

What am I doing wrong?

@ivanstepanovftw
Copy link
Author

@HareInWeed,你能帮帮我吗?我不明白我做错了什么。

@mamumi
Copy link

mamumi commented Aug 21, 2024

ivanstepanovftw Could you share how it works?

@ivanstepanovftw
Copy link
Author

@mamumi Yes, sharing

@Adz2323
Copy link

Adz2323 commented Jan 12, 2025

#include <gec/curve/secp256k1.hpp>
#include <gec/bigint/mixin/random.hpp>
#include
#include
#include
#include

using namespace gec::bigint::literal;

struct CustomRng
{
std::mt19937_64 gen;
CustomRng() : gen(std::random_device{}()) {}

template <typename T>
GEC_HD T operator()(T higher) { return gen() % higher; }

template <typename T>
GEC_HD T operator()(T lower, T higher) { return lower + (gen() % (higher - lower)); }

template <typename T>
GEC_HD T operator()() { return static_cast<T>(gen()); }

};

namespace gec
{
template <>
struct GecRng
{
CustomRng rng;
GecRng(CustomRng r) : rng(r) {}

    template <typename T>
    GEC_HD T sample() { return rng.template operator()<T>(); }

    template <typename T>
    GEC_HD T sample(T higher) { return rng(higher); }

    template <typename T>
    GEC_HD T sample(T lower, T higher) { return rng(lower, higher); }
};

}

template
std::string to_hex(const T &value)
{
std::stringstream ss;
ss << std::hex << std::setfill('0');
const auto &arr = value.array();
for (size_t i = T::LimbN; i > 0; --i)
{
ss << std::setw(16) << arr[i - 1];
}
return ss.str();
}

void generate_keypair()
{
using namespace gec::curve::secp256k1;
using Point = Curve<>;

CustomRng rng_base;
auto rng = gec::GecRng<CustomRng>(rng_base);

// Generate private key
Scalar private_key;
do
{
    Scalar::sample(private_key, rng);
} while (private_key >= Scalar::mod() || private_key.is_zero());

// Generate public key
Point public_key;
Point::mul(public_key, private_key, Gen); // Don't convert private key to Montgomery form
Point::to_affine(public_key);

Field x_coord = public_key.x();
Field y_coord = public_key.y();
Field::from_montgomery(x_coord, x_coord);
Field::from_montgomery(y_coord, y_coord);

std::cout << "Private key: " << to_hex(private_key) << std::endl;
std::cout << "Public key (uncompressed):\n04"
          << to_hex(x_coord)
          << to_hex(y_coord) << std::endl;

}

int main()
{
try
{
generate_keypair();
return 0;
}
catch (const std::exception &e)
{
std::cerr << "Error: " << e.what() << std::endl;
return 1;
}
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants