## std::math::ecgfp5::group | Procedure | Description | | ----------- | ------------- | | validate | Given an encoded elliptic curve point `w` s.t. it's expressed using
an element ∈ GF(p^5) \| p = 2^64 - 2^32 + 1, this routine verifies whether
given point can be successfully decoded or not

Expected stack state

[w0, w1, w2, w3, w4, ...]

Final stack state

[flg, ...]

If w can be decoded, flg = 1
Else flg = 0

Note, if w = (0, 0, 0, 0, 0), it can be successfully decoded to point
at infinity i.e. flg = 1, in that case.

See https://github.com/pornin/ecgfp5/blob/ce059c6/python/ecGFp5.py#L1043-L1052
for reference implementation
| | decode | Given an encoded elliptic curve point `w` s.t. it's expressed using
an element ∈ GF(p^5) \| p = 2^64 - 2^32 + 1, this routine attempts to decode
it into x, y coordinates, along with boolean field element denoting whether it's
point-at-infinity or not.

Expected stack state

[w0, w1, w2, w3, w4, ...]

Final state state

[x0, x1, x2, x3, x4, y0, y1, y2, y3, y4, inf, flg, ...]

If `w` has be decoded, flg = 1
Else flg = 0 and x, y = (0, 0)

Note, when w = (0, 0, 0, 0, 0), it will be successfully decoded to
point-at-infinity i.e. x, y = (0, 0) and flg = 1

See https://github.com/pornin/ecgfp5/blob/ce059c6/python/ecGFp5.py#L1022-L1041
for reference implementation
| | encode | Given an elliptic curve point as Weierstraß coordinates (X, Y) along with
boolean field element `inf`, denoting whether this is point-at-infinity or not,
this routine encodes it to a single element ∈ GF(p^5) \| p = 2^64 - 2^32 + 1

Expected stack state

[x0, x1, x2, x3, x4, y0, y1, y2, y3, y4, inf, ...]

Final stack state

[w0, w1, w2, w3, w4, ...]

Note, when inf = 1, encoded point w = (0, 0, 0, 0, 0)

See https://github.com/pornin/ecgfp5/blob/ce059c6/python/ecGFp5.py#L1214-L1216
for reference implementation.
| | add | Given two elliptic curve points ( say a, b ) as Weierstraß coordinates (X, Y) on stack,
this routine computes elliptic curve point c, resulting from a + b.

Following point addition formula is complete and it works when two points are
same/ different or input operands are point-at-infinity.

Expected stack state

[x1_0, x1_1, x1_2, x1_3, x1_4, y1_0, y1_1, y1_2, y1_3, y1_4, inf1, x2_0, x2_1, x2_2, x2_3, x2_4, y2_0, y2_1, y2_2, y2_3, y2_4, inf2, ...]

s.t. x1_{0..5} -> x1, y1_{0..5} -> y1 \|> a = (x1, y1, inf1)
x2_{0..5} -> x2, y2_{0..5} -> y2 \|> b = (x2, y2, inf2)

Final stack state

[x3_0, x3_1, x3_2, x3_3, x3_4, y3_0, y3_1, y3_2, y3_3, y3_4, inf3, ...]

Read point addition section ( on page 8 ) of https://ia.cr/2022/274
For reference implementation see https://github.com/pornin/ecgfp5/blob/ce059c6/python/ecGFp5.py#L1228-L1255
| | double | Given one elliptic curve point ( say a ) as Weierstraß coordinates (X, Y) on stack,
this routine computes elliptic curve point b s.t. b = 2 * a.

Following point doubling formula is complete and it works only when input operand is
a non-infinity point, then resulting point b should also be non-infinity.

Note, result of add(a, b) = double(a) \| a = b

Expected stack state

[x0, x1, x2, x3, x4, y0, y1, y2, y3, y4, inf, ...]

s.t. x{0..5} -> x, y{0..5} -> y \|> a = (x, y, inf)

Final stack state

[x'0, x'1, x'2, x'3, x'4, y'0, y'1, y'2, y'3, y'4, inf, ...]

Read point addition section ( on page 8 ) of https://ia.cr/2022/274
For reference implementation see https://github.com/pornin/ecgfp5/blob/ce059c6/python/ecGFp5.py#L1270-L1280
| | mul | Given an elliptic curve point ( say a ) as Weierstraß coordinates (X, Y) and a 319 -bit scalar ( say e )
on stack, this routine computes elliptic curve point b s.t. b = e * a, using double-and-add technique.

Scalar e should be lesser than 1067993516717146951041484916571792702745057740581727230159139685185762082554198619328292418486241 ( prime number ).
Note, scalar e should be provided as 10 limbs on stack, each of 32 -bit, representing it in radix-2^32 form.

Given a scalar e ( as arbitrary width big integer ), following python code snippet should convert it to desired input form

[(a >> (32*i)) & 0xffff_ffff for i in range(10)]

Expected stack state

[x0, x1, x2, x3, x4, y0, y1, y2, y3, y4, inf, e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, ...]

Point a = (x, y, inf)
Scalar e = (e0, e1, e2, e3, e4, e5, e6, e7, e8, e9)

Final stack state

[x'0, x'1, x'2, x'3, x'4, y'0, y'1, y'2, y'3, y'4, inf, ...]

Point b = (x', y' inf') \| b = e * a

See https://github.com/itzmeanjan/secp256k1/blob/cbbe199/point.py#L174-L186 for source of inpiration.
| | gen_mul | Given a 319 -bit scalar ( say e ) on stack, this routine computes elliptic curve point
b s.t. b = e * G, using double-and-add technique \| G = conventional group generator point.

Group generator point https://github.com/pornin/ecgfp5/blob/ce059c6/rust/src/curve.rs#L67-L83

Scalar e should be lesser than N ( = 1067993516717146951041484916571792702745057740581727230159139685185762082554198619328292418486241 ).
Note, scalar e should be provided as 10 limbs on stack, each of 32 -bit, representing it in radix-2^32 form.

Given a 319 -bit scalar e, following python code snippet should convert it to
desired input form i.e. radix-2^32 representation, having ten 32 -bit limbs

[(e >> (32*i)) & 0xffff_ffff for i in range(10)]

Expected stack state

[e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, ...]

Scalar e = (e0, e1, e2, e3, e4, e5, e6, e7, e8, e9)

Final stack state

[x0, x1, x2, x3, x4, y0, y1, y2, y3, y4, inf, ...]

Point b = (x, y, inf) \| b = e * G

See https://github.com/itzmeanjan/secp256k1/blob/cbbe199/point.py#L174-L186 for source of inpiration.
|