How to multiply scalar value with point on NIST P-256 curve?

⚓ rust    📅 2025-05-21    👤 surdeus    👁️ 5      

surdeus

Warning

This post was published 39 days ago. The information described in this article may have changed.

Hello.

I need to implement the following "elliptic curve" calculation in Rust langauge, where w is a scalar and G is a point on the NIST P-256 curve:

L = w * G

Test vector is as follows:

w   = 0x44363d157f471221b1e75e596ff4714a712b9578301665d84ec17004952523a8
G.x = 0x6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296
G.y = 0x4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5

Expected result:

L.x = 0xff69eb6086938b3cce2c9e64dcacea1a925918e75e8c17948d316322d370123f
L.y = 0x69132aed7398919e6e6614f7627b0a54060c5a8c0d93d2754166ab10fea6a8ff

For reference, here is my working implementation in Python:

from ecdsa.curves import NIST256p
from ecdsa.ellipticcurve import PointJacobi

scalar_w = bytes.fromhex("44363d157f471221b1e75e596ff4714a712b9578301665d84ec17004952523a8")
point_Gx = bytes.fromhex("6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296")
point_Gy = bytes.fromhex("4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5")

w = int.from_bytes(scalar_w, 'big')
G = PointJacobi.from_bytes(NIST256p.curve, b'\x04' + point_Gx + point_Gy)
L = w * G

print(f"L.x = 0x{L.x().to_bytes(32, 'big').hex()}")
print(f"L.y = 0x{L.y().to_bytes(32, 'big').hex()}")

But how to do this in Rust?

I have tried with the p256 package (from Rust Crypto), and this is what I got so far:

use p256::AffinePoint;
use p256::EncodedPoint;
use p256::FieldBytes;
use p256::NonZeroScalar;
use p256::ProjectivePoint;

#[allow(non_snake_case)]
fn main() {
    let scalar_w = hex::decode("44363d157f471221b1e75e596ff4714a712b9578301665d84ec17004952523a8").unwrap();
    let point_Gx = hex::decode("6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296").unwrap();
    let point_Gy = hex::decode("4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5").unwrap();

    let w = NonZeroScalar::from_repr(*FieldBytes::from_slice(&scalar_w[..])).unwrap();
    let G = EncodedPoint::from_bytes([&[ 0x04u8 ], &point_Gx[..], &point_Gy[..]].concat()).unwrap();

    /* let G = AffinePoint::try_from(G).unwrap();
    let G = ProjectivePoint::from(G); */

    println!("w: {:?}", w.to_string());
    println!("G: {:?}", G);

    // let L = w * G; <-- How to do this ????
}

But now I'm stuck and don't know how to do the multiplication :thinking:

Also, do I need to convert EncodedPoint to AffinePoint and/or ProjectivePoint first ???

(I think PointJacobi on Python is a sort of a projective point, though I'm not a math expert)

Any help would be much appreciated!

Thank you.

1 post - 1 participant

Read full topic

🏷️ rust_feed