Post
Topic
Board Development & Technical Discussion
Re: Determine if a public key point y is negative or positive, odd or even?
by
bjpark
on 22/01/2025, 21:16:14 UTC
i can do it
Code:
import random
import ecdsa
import binascii

# Define the range
def generate_random_values():
    a = random.randint(2**134, 2**135)
    am = 10**37
    b = a - am

    # Set pma and pmb: both values must have the same sign
    sign = random.choice([1, -1])  # Set as positive or negative
    pma = sign * a
    pmb = sign * b

    return a, b, am, pma, pmb

# Define the order N of the secp256k1 curve
N = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141

# Function to generate public key from private key
def generate_public_key(private_key_int):
    # Convert the private key to 32-byte format
    private_key_bytes = abs(private_key_int).to_bytes(32, byteorder="big", signed=True)
   
    # Generate elliptic curve public key (secp256k1)
    sk = ecdsa.SigningKey.from_string(private_key_bytes, curve=ecdsa.SECP256k1)
    vk = sk.verifying_key
   
    # Create uncompressed public key format
    public_key_bytes_uncompressed = b"\x04" + vk.to_string()
   
    # Determine the prefix of the compressed public key based on the sign of the private key
    if private_key_int < 0:
        public_key_bytes_compressed = (
            b"\x03" + vk.to_string()[:32] if vk.to_string()[-1] % 2 == 0 else b"\x02" + vk.to_string()[:32]
        )
    else:
        public_key_bytes_compressed = (
            b"\x02" + vk.to_string()[:32] if vk.to_string()[-1] % 2 == 0 else b"\x03" + vk.to_string()[:32]
        )
   
    # Convert the public key to a hexadecimal string
    public_key_uncompressed = binascii.hexlify(public_key_bytes_uncompressed).decode()
    public_key_compressed = binascii.hexlify(public_key_bytes_compressed).decode()
   
    return public_key_uncompressed, public_key_compressed

# Adjust private key representation
def adjust_private_key(private_key_int):
    if private_key_int < 0:
        adjusted_key = N + private_key_int
        return f"0x{adjusted_key:064x}"
    else:
        return str(private_key_int)

# Generate and output results 10 times
all_public_keys = []  # List to store public keys
for i in range(1, 31):
    print(f"\n=== Random Output {i} ===")
    a, b, am, pma, pmb = generate_random_values()
    public_key_a_uncompressed, public_key_a_compressed = generate_public_key(pma)
    public_key_b_uncompressed, public_key_b_compressed = generate_public_key(pmb)

    print("a:", a)
    print("b:", b)
    print("am:", am)
    print("pma (Private Key a):", adjust_private_key(pma))
    print("pmb (Private Key b):", adjust_private_key(pmb))

    print("public_key_a (Compressed Public Key a):", public_key_a_compressed)
    print("public_key_b (Compressed Public Key b):", public_key_b_compressed)

    # Store public keys
    all_public_keys.append((public_key_a_compressed, public_key_b_compressed))

    # Add sign of pma and pmb
    sign_a = "+" if pma > 0 else "-"
    sign_b = "+" if pmb > 0 else "-"

    print("Sign of pma:", sign_a)
    print("Sign of pmb:", sign_b)

# Additional public key output
print("What has been printed above is what you have, and if you provide only what is printed now, I can match positive and negative signs.")
print("\nAdditional public key output:")
for i, (pub_a, pub_b) in enumerate(all_public_keys, start=1):
    print(f"\n=== Random Output {i} ===")
    print("public_key_a (Compressed Public Key a):", pub_a)
    print("public_key_b (Compressed Public Key b):", pub_b)

If my friends give me 30 problems, I can submit the answers for the signs of pma (Sign of pma:) within 30 minutes. You can easily test me.